From 48a77a46457d0578b9c1dd637b71455f513077a9 Mon Sep 17 00:00:00 2001 From: Dewmal Date: Sun, 19 Jan 2025 20:08:12 +0530 Subject: [PATCH] remove old code from repo --- Cargo.lock | 21 - Cargo.toml | 2 +- bindings/ceylon-js/.appveyor.yml | 11 - bindings/ceylon-js/.github/dependabot.yml | 8 - bindings/ceylon-js/.gitignore | 6 - bindings/ceylon-js/.travis.yml | 69 --- bindings/ceylon-js/Cargo.toml | 29 -- bindings/ceylon-js/LICENSE_APACHE | 201 --------- bindings/ceylon-js/LICENSE_MIT | 25 -- bindings/ceylon-js/README.md | 84 ---- bindings/ceylon-js/src/lib.rs | 16 - bindings/ceylon-js/src/utils.rs | 10 - bindings/ceylon-js/tests/web.rs | 13 - .../ceylon/ceylon/__core/agent/__init__.py | 0 bindings/ceylon/ceylon/__core/agent/admin.py | 47 -- bindings/ceylon/ceylon/__core/agent/agent.py | 29 -- bindings/ceylon/ceylon/__core/agent/agents.py | 117 ----- bindings/ceylon/ceylon/__core/agent/common.py | 66 --- .../ceylon/__core/agent/types/__init__.py | 19 - .../__core/agent/types/agent_request.py | 26 -- .../ceylon/ceylon/__core/agent/types/job.py | 129 ------ .../ceylon/__core/agent/types/job_step.py | 16 - .../ceylon/ceylon/__core/agents/__init__.py | 0 .../ceylon/__core/agents/worker_agent.py | 265 ------------ .../ceylon/ceylon/__core/auto/__init__.py | 0 .../ceylon/__core/auto/manager/__init__.py | 0 .../__core/auto/manager/abstract_manager.py | 36 -- .../__core/auto/manager/agent_taskmanager.py | 23 - .../ceylon/__core/auto/manager/cli_manager.py | 48 --- bindings/ceylon/ceylon/__core/auto/model.py | 75 ---- .../ceylon/__core/auto/worker/__init__.py | 0 .../__core/auto/worker/agent_executor.py | 29 -- .../ceylon/ceylon/__core/core/__init__.py | 0 bindings/ceylon/ceylon/__core/core/admin.py | 57 --- bindings/ceylon/ceylon/__core/core/worker.py | 65 --- bindings/ceylon/ceylon/__core/in/__init__.py | 0 bindings/ceylon/ceylon/__core/llm/__init__.py | 2 - .../ceylon/ceylon/__core/llm/llm/__init__.py | 0 .../ceylon/__core/llm/llm/llm_executor.py | 60 --- .../ceylon/__core/llm/llm_task_coordinator.py | 400 ------------------ .../ceylon/__core/llm/llm_task_operator.py | 128 ------ .../ceylon/__core/llm/tools/__init__.py | 0 .../__core/llm/tools/file_publisher_tool.py | 63 --- .../ceylon/__core/llm/tools/search_tool.py | 43 -- .../ceylon/ceylon/__core/task/__init__.py | 3 - .../ceylon/__core/task/task_coordinator.py | 139 ------ .../task/task_human_intractive_operator.py | 18 - .../ceylon/__core/task/task_operation.py | 313 -------------- .../ceylon/__core/task/task_operator.py | 80 ---- bindings/ceylon/ceylon/__core/task/test.py | 63 --- .../ceylon/ceylon/__core/utils/__init__.py | 0 .../ceylon/__core/utils/agent_monitor.py | 28 -- bindings/ceylon/ceylon/agents/__init__.py | 0 bindings/ceylon/ceylon/agents/agents.py | 116 ----- bindings/ceylon/tests/ceylon_agent_test.py | 61 --- .../ceylon/tests/example_project/__init__.py | 0 .../example_project/chat_gpt_task_manager.py | 113 ----- .../task_manager_ceylon_result.py | 112 ----- .../example_project/tasks_2024-12-12.csv | 2 - .../example_project/tasks_2024-12-15.csv | 2 - bindings/ceylon/tests/llm_agen_test.py | 108 ----- bindings/ceylon/tests/llm_agents/__init__.py | 0 .../task_manager-ollama-sub-task-automated.py | 228 ---------- .../task_manager-ollama-sub-task.py | 152 ------- ...llama-task-automation-with-dependencies.py | 117 ----- .../tests/llm_agents/task_manager-ollama.py | 129 ------ .../tests/llm_agents/task_manager-open-ai.py | 128 ------ .../llm_agents/tasks_with_dependencies.py | 124 ------ bindings/ceylon/tests/llm_test/__init__.py | 0 .../ceylon/tests/llm_test/llm_test_open_ai.py | 67 --- bindings/ceylon/tests/llm_test/llm_writer.py | 85 ---- .../ceylon/tests/llm_test/stock_analyser.py | 83 ---- .../tests/llm_test/stock_analyser_async.py | 85 ---- .../ceylon/tests/server_agents/__init__.py | 0 .../ceylon/tests/server_agents/agent_one.py | 46 -- .../tests/server_agents/monitor_agent.py | 75 ---- .../tests/server_agents/server_agent.py | 9 - bindings/ceylon/tests/single_llm_agent.py | 49 --- bindings/ceylon/tests/stm/__init__.py | 0 bindings/ceylon/tests/stm/agent_stm.py | 23 - bindings/ceylon/tests/stm/main.py | 72 ---- bindings/ceylon/tests/tasks/__init__.py | 0 ...cle-writer-agents-gen-with-tools-openai.py | 167 -------- .../article-writer-agents-gen-with-tools.py | 166 -------- .../tests/tasks/article-writer-agents-gen.py | 118 ------ .../tests/tasks/article-writer-agents.py | 76 ---- bindings/ceylon/tests/tasks/fw_tool.py | 49 --- .../tests/tasks/llm_software_agency-gorq.py | 80 ---- .../ceylon/tests/tasks/llm_software_agency.py | 158 ------- .../ceylon/tests/tasks/manage_tasks-agents.py | 103 ----- bindings/ceylon/tests/tasks/manage_tasks.py | 186 -------- bindings/ceylon/tests/tasks/sample_game.py | 198 --------- bindings/ceylon/tests/tasks/task_agent.py | 173 -------- .../tests/tasks/task_with_human_inputs.py | 43 -- .../tasks/task_with_human_inputs_llma.py | 60 --- bindings/ceylon/tests/test_agent.py | 24 -- bindings/ceylon/tests/test_agents.py | 110 ----- bindings/ceylon/tests/test_prompt.py | 10 - bindings/ceylon/tests/test_worker/__init__.py | 0 bindings/ceylon/tests/test_worker/auction.py | 117 ----- .../ceylon/tests/test_worker/chat_group.py | 0 .../tests/test_worker/meeting_schedular.py | 156 ------- .../tests/test_worker/remote/__init__.py | 0 .../tests/test_worker/remote/remote_admin.py | 26 -- .../tests/test_worker/remote/remote_worker.py | 18 - .../ceylon/tests/test_worker/task_manager.py | 100 ----- bindings/ceylon/tests/test_worker/test.py | 86 ---- .../tests/test_worker/test_game_board.py | 80 ---- bindings/ceylon/tests/tools/__init__.py | 0 .../tests/tools/file_publisher_tool_test.py | 55 --- 110 files changed, 1 insertion(+), 7226 deletions(-) delete mode 100644 bindings/ceylon-js/.appveyor.yml delete mode 100644 bindings/ceylon-js/.github/dependabot.yml delete mode 100644 bindings/ceylon-js/.gitignore delete mode 100644 bindings/ceylon-js/.travis.yml delete mode 100644 bindings/ceylon-js/Cargo.toml delete mode 100644 bindings/ceylon-js/LICENSE_APACHE delete mode 100644 bindings/ceylon-js/LICENSE_MIT delete mode 100644 bindings/ceylon-js/README.md delete mode 100644 bindings/ceylon-js/src/lib.rs delete mode 100644 bindings/ceylon-js/src/utils.rs delete mode 100644 bindings/ceylon-js/tests/web.rs delete mode 100644 bindings/ceylon/ceylon/__core/agent/__init__.py delete mode 100644 bindings/ceylon/ceylon/__core/agent/admin.py delete mode 100644 bindings/ceylon/ceylon/__core/agent/agent.py delete mode 100644 bindings/ceylon/ceylon/__core/agent/agents.py delete mode 100644 bindings/ceylon/ceylon/__core/agent/common.py delete mode 100644 bindings/ceylon/ceylon/__core/agent/types/__init__.py delete mode 100644 bindings/ceylon/ceylon/__core/agent/types/agent_request.py delete mode 100644 bindings/ceylon/ceylon/__core/agent/types/job.py delete mode 100644 bindings/ceylon/ceylon/__core/agent/types/job_step.py delete mode 100644 bindings/ceylon/ceylon/__core/agents/__init__.py delete mode 100644 bindings/ceylon/ceylon/__core/agents/worker_agent.py delete mode 100644 bindings/ceylon/ceylon/__core/auto/__init__.py delete mode 100644 bindings/ceylon/ceylon/__core/auto/manager/__init__.py delete mode 100644 bindings/ceylon/ceylon/__core/auto/manager/abstract_manager.py delete mode 100644 bindings/ceylon/ceylon/__core/auto/manager/agent_taskmanager.py delete mode 100644 bindings/ceylon/ceylon/__core/auto/manager/cli_manager.py delete mode 100644 bindings/ceylon/ceylon/__core/auto/model.py delete mode 100644 bindings/ceylon/ceylon/__core/auto/worker/__init__.py delete mode 100644 bindings/ceylon/ceylon/__core/auto/worker/agent_executor.py delete mode 100644 bindings/ceylon/ceylon/__core/core/__init__.py delete mode 100644 bindings/ceylon/ceylon/__core/core/admin.py delete mode 100644 bindings/ceylon/ceylon/__core/core/worker.py delete mode 100644 bindings/ceylon/ceylon/__core/in/__init__.py delete mode 100644 bindings/ceylon/ceylon/__core/llm/__init__.py delete mode 100644 bindings/ceylon/ceylon/__core/llm/llm/__init__.py delete mode 100644 bindings/ceylon/ceylon/__core/llm/llm/llm_executor.py delete mode 100644 bindings/ceylon/ceylon/__core/llm/llm_task_coordinator.py delete mode 100644 bindings/ceylon/ceylon/__core/llm/llm_task_operator.py delete mode 100644 bindings/ceylon/ceylon/__core/llm/tools/__init__.py delete mode 100644 bindings/ceylon/ceylon/__core/llm/tools/file_publisher_tool.py delete mode 100644 bindings/ceylon/ceylon/__core/llm/tools/search_tool.py delete mode 100644 bindings/ceylon/ceylon/__core/task/__init__.py delete mode 100644 bindings/ceylon/ceylon/__core/task/task_coordinator.py delete mode 100644 bindings/ceylon/ceylon/__core/task/task_human_intractive_operator.py delete mode 100644 bindings/ceylon/ceylon/__core/task/task_operation.py delete mode 100644 bindings/ceylon/ceylon/__core/task/task_operator.py delete mode 100644 bindings/ceylon/ceylon/__core/task/test.py delete mode 100644 bindings/ceylon/ceylon/__core/utils/__init__.py delete mode 100644 bindings/ceylon/ceylon/__core/utils/agent_monitor.py delete mode 100644 bindings/ceylon/ceylon/agents/__init__.py delete mode 100644 bindings/ceylon/ceylon/agents/agents.py delete mode 100644 bindings/ceylon/tests/ceylon_agent_test.py delete mode 100644 bindings/ceylon/tests/example_project/__init__.py delete mode 100644 bindings/ceylon/tests/example_project/chat_gpt_task_manager.py delete mode 100644 bindings/ceylon/tests/example_project/task_manager_ceylon_result.py delete mode 100644 bindings/ceylon/tests/example_project/tasks_2024-12-12.csv delete mode 100644 bindings/ceylon/tests/example_project/tasks_2024-12-15.csv delete mode 100644 bindings/ceylon/tests/llm_agen_test.py delete mode 100644 bindings/ceylon/tests/llm_agents/__init__.py delete mode 100644 bindings/ceylon/tests/llm_agents/task_manager-ollama-sub-task-automated.py delete mode 100644 bindings/ceylon/tests/llm_agents/task_manager-ollama-sub-task.py delete mode 100644 bindings/ceylon/tests/llm_agents/task_manager-ollama-task-automation-with-dependencies.py delete mode 100644 bindings/ceylon/tests/llm_agents/task_manager-ollama.py delete mode 100644 bindings/ceylon/tests/llm_agents/task_manager-open-ai.py delete mode 100644 bindings/ceylon/tests/llm_agents/tasks_with_dependencies.py delete mode 100644 bindings/ceylon/tests/llm_test/__init__.py delete mode 100644 bindings/ceylon/tests/llm_test/llm_test_open_ai.py delete mode 100644 bindings/ceylon/tests/llm_test/llm_writer.py delete mode 100644 bindings/ceylon/tests/llm_test/stock_analyser.py delete mode 100644 bindings/ceylon/tests/llm_test/stock_analyser_async.py delete mode 100644 bindings/ceylon/tests/server_agents/__init__.py delete mode 100644 bindings/ceylon/tests/server_agents/agent_one.py delete mode 100644 bindings/ceylon/tests/server_agents/monitor_agent.py delete mode 100644 bindings/ceylon/tests/server_agents/server_agent.py delete mode 100644 bindings/ceylon/tests/single_llm_agent.py delete mode 100644 bindings/ceylon/tests/stm/__init__.py delete mode 100644 bindings/ceylon/tests/stm/agent_stm.py delete mode 100644 bindings/ceylon/tests/stm/main.py delete mode 100644 bindings/ceylon/tests/tasks/__init__.py delete mode 100644 bindings/ceylon/tests/tasks/article-writer-agents-gen-with-tools-openai.py delete mode 100644 bindings/ceylon/tests/tasks/article-writer-agents-gen-with-tools.py delete mode 100644 bindings/ceylon/tests/tasks/article-writer-agents-gen.py delete mode 100644 bindings/ceylon/tests/tasks/article-writer-agents.py delete mode 100644 bindings/ceylon/tests/tasks/fw_tool.py delete mode 100644 bindings/ceylon/tests/tasks/llm_software_agency-gorq.py delete mode 100644 bindings/ceylon/tests/tasks/llm_software_agency.py delete mode 100644 bindings/ceylon/tests/tasks/manage_tasks-agents.py delete mode 100644 bindings/ceylon/tests/tasks/manage_tasks.py delete mode 100644 bindings/ceylon/tests/tasks/sample_game.py delete mode 100644 bindings/ceylon/tests/tasks/task_agent.py delete mode 100644 bindings/ceylon/tests/tasks/task_with_human_inputs.py delete mode 100644 bindings/ceylon/tests/tasks/task_with_human_inputs_llma.py delete mode 100644 bindings/ceylon/tests/test_agent.py delete mode 100644 bindings/ceylon/tests/test_agents.py delete mode 100644 bindings/ceylon/tests/test_prompt.py delete mode 100644 bindings/ceylon/tests/test_worker/__init__.py delete mode 100644 bindings/ceylon/tests/test_worker/auction.py delete mode 100644 bindings/ceylon/tests/test_worker/chat_group.py delete mode 100644 bindings/ceylon/tests/test_worker/meeting_schedular.py delete mode 100644 bindings/ceylon/tests/test_worker/remote/__init__.py delete mode 100644 bindings/ceylon/tests/test_worker/remote/remote_admin.py delete mode 100644 bindings/ceylon/tests/test_worker/remote/remote_worker.py delete mode 100644 bindings/ceylon/tests/test_worker/task_manager.py delete mode 100644 bindings/ceylon/tests/test_worker/test.py delete mode 100644 bindings/ceylon/tests/test_worker/test_game_board.py delete mode 100644 bindings/ceylon/tests/tools/__init__.py delete mode 100644 bindings/ceylon/tests/tools/file_publisher_tool_test.py diff --git a/Cargo.lock b/Cargo.lock index fe2e3c79..4dc6e31d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -448,17 +448,6 @@ dependencies = [ "uniffi", ] -[[package]] -name = "ceylon-ai" -version = "0.1.0" -dependencies = [ - "ceylon", - "console_error_panic_hook", - "sangedama", - "wasm-bindgen", - "wasm-bindgen-test", -] - [[package]] name = "ceylon-core" version = "0.1.0" @@ -524,16 +513,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "console_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if", - "wasm-bindgen", -] - [[package]] name = "const-oid" version = "0.9.6" diff --git a/Cargo.toml b/Cargo.toml index 3dc00575..65bcf5a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,3 @@ [workspace] -members = ["libs/sangedama", "bindings/ceylon", "bindings/ceylon-js", "libs/ceylon-core"] +members = ["libs/sangedama", "bindings/ceylon", "libs/ceylon-core"] resolver = "2" diff --git a/bindings/ceylon-js/.appveyor.yml b/bindings/ceylon-js/.appveyor.yml deleted file mode 100644 index 50910bd6..00000000 --- a/bindings/ceylon-js/.appveyor.yml +++ /dev/null @@ -1,11 +0,0 @@ -install: - - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe - - if not defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly - - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin - - rustc -V - - cargo -V - -build: false - -test_script: - - cargo test --locked diff --git a/bindings/ceylon-js/.github/dependabot.yml b/bindings/ceylon-js/.github/dependabot.yml deleted file mode 100644 index 7377d375..00000000 --- a/bindings/ceylon-js/.github/dependabot.yml +++ /dev/null @@ -1,8 +0,0 @@ -version: 2 -updates: -- package-ecosystem: cargo - directory: "/" - schedule: - interval: daily - time: "08:00" - open-pull-requests-limit: 10 diff --git a/bindings/ceylon-js/.gitignore b/bindings/ceylon-js/.gitignore deleted file mode 100644 index 4e301317..00000000 --- a/bindings/ceylon-js/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/target -**/*.rs.bk -Cargo.lock -bin/ -pkg/ -wasm-pack.log diff --git a/bindings/ceylon-js/.travis.yml b/bindings/ceylon-js/.travis.yml deleted file mode 100644 index 7a913256..00000000 --- a/bindings/ceylon-js/.travis.yml +++ /dev/null @@ -1,69 +0,0 @@ -language: rust -sudo: false - -cache: cargo - -matrix: - include: - - # Builds with wasm-pack. - - rust: beta - env: RUST_BACKTRACE=1 - addons: - firefox: latest - chrome: stable - before_script: - - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) - - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) - - cargo install-update -a - - curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f - script: - - cargo generate --git . --name testing - # Having a broken Cargo.toml (in that it has curlies in fields) anywhere - # in any of our parent dirs is problematic. - - mv Cargo.toml Cargo.toml.tmpl - - cd testing - - wasm-pack build - - wasm-pack test --chrome --firefox --headless - - # Builds on nightly. - - rust: nightly - env: RUST_BACKTRACE=1 - before_script: - - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) - - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) - - cargo install-update -a - - rustup target add wasm32-unknown-unknown - script: - - cargo generate --git . --name testing - - mv Cargo.toml Cargo.toml.tmpl - - cd testing - - cargo check - - cargo check --target wasm32-unknown-unknown - - cargo check --no-default-features - - cargo check --target wasm32-unknown-unknown --no-default-features - - cargo check --no-default-features --features console_error_panic_hook - - cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook - - cargo check --no-default-features --features "console_error_panic_hook wee_alloc" - - cargo check --target wasm32-unknown-unknown --no-default-features --features "console_error_panic_hook wee_alloc" - - # Builds on beta. - - rust: beta - env: RUST_BACKTRACE=1 - before_script: - - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) - - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) - - cargo install-update -a - - rustup target add wasm32-unknown-unknown - script: - - cargo generate --git . --name testing - - mv Cargo.toml Cargo.toml.tmpl - - cd testing - - cargo check - - cargo check --target wasm32-unknown-unknown - - cargo check --no-default-features - - cargo check --target wasm32-unknown-unknown --no-default-features - - cargo check --no-default-features --features console_error_panic_hook - - cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook - # Note: no enabling the `wee_alloc` feature here because it requires - # nightly for now. diff --git a/bindings/ceylon-js/Cargo.toml b/bindings/ceylon-js/Cargo.toml deleted file mode 100644 index 86c51590..00000000 --- a/bindings/ceylon-js/Cargo.toml +++ /dev/null @@ -1,29 +0,0 @@ -[package] -name = "ceylon-ai" -version = "0.1.0" -authors = ["dewma "] -edition = "2018" - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -default = ["console_error_panic_hook"] - -[dependencies] -wasm-bindgen = "0.2.99" -sangedama = { path = "../../libs/sangedama", features = ["wasm"] } -ceylon = { path = "../ceylon" } - -# The `console_error_panic_hook` crate provides better debugging of panics by -# logging them with `console.error`. This is great for development, but requires -# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for -# code size when deploying. -console_error_panic_hook = { version = "0.1.7", optional = true } - -[dev-dependencies] -wasm-bindgen-test = "0.3.34" - -[profile.release] -# Tell `rustc` to optimize for small code size. -opt-level = "s" diff --git a/bindings/ceylon-js/LICENSE_APACHE b/bindings/ceylon-js/LICENSE_APACHE deleted file mode 100644 index 11069edd..00000000 --- a/bindings/ceylon-js/LICENSE_APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/bindings/ceylon-js/LICENSE_MIT b/bindings/ceylon-js/LICENSE_MIT deleted file mode 100644 index 312e4c8a..00000000 --- a/bindings/ceylon-js/LICENSE_MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2018 dewma - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/bindings/ceylon-js/README.md b/bindings/ceylon-js/README.md deleted file mode 100644 index 6b684085..00000000 --- a/bindings/ceylon-js/README.md +++ /dev/null @@ -1,84 +0,0 @@ -
- -

wasm-pack-template

- - A template for kick starting a Rust and WebAssembly project using wasm-pack. - -

- Build Status -

- -

- Tutorial - | - Chat -

- - Built with 🦀🕸 by The Rust and WebAssembly Working Group -
- -## About - -[**📚 Read this template tutorial! 📚**][template-docs] - -This template is designed for compiling Rust libraries into WebAssembly and -publishing the resulting package to NPM. - -Be sure to check out [other `wasm-pack` tutorials online][tutorials] for other -templates and usages of `wasm-pack`. - -[tutorials]: https://rustwasm.github.io/docs/wasm-pack/tutorials/index.html -[template-docs]: https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html - -## 🚴 Usage - -### 🐑 Use `cargo generate` to Clone this Template - -[Learn more about `cargo generate` here.](https://github.com/ashleygwilliams/cargo-generate) - -``` -cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project -cd my-project -``` - -### 🛠️ Build with `wasm-pack build` - -``` -wasm-pack build -``` - -### 🔬 Test in Headless Browsers with `wasm-pack test` - -``` -wasm-pack test --headless --firefox -``` - -### 🎁 Publish to NPM with `wasm-pack publish` - -``` -wasm-pack publish -``` - -## 🔋 Batteries Included - -* [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) for communicating - between WebAssembly and JavaScript. -* [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook) - for logging panic messages to the developer console. -* `LICENSE-APACHE` and `LICENSE-MIT`: most Rust projects are licensed this way, so these are included for you - -## License - -Licensed under either of - -* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) -* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) - -at your option. - -### Contribution - -Unless you explicitly state otherwise, any contribution intentionally -submitted for inclusion in the work by you, as defined in the Apache-2.0 -license, shall be dual licensed as above, without any additional terms or -conditions. diff --git a/bindings/ceylon-js/src/lib.rs b/bindings/ceylon-js/src/lib.rs deleted file mode 100644 index f902d1b0..00000000 --- a/bindings/ceylon-js/src/lib.rs +++ /dev/null @@ -1,16 +0,0 @@ -mod utils; - -use ceylon::WorkerAgent; -use wasm_bindgen::prelude::*; - -use wasm_bindgen::prelude::*; - -#[wasm_bindgen] -extern "C" { - fn alert(s: &str); -} - -#[wasm_bindgen] -pub fn greet() { - alert("Hello, ceylon-js!"); -} diff --git a/bindings/ceylon-js/src/utils.rs b/bindings/ceylon-js/src/utils.rs deleted file mode 100644 index b1d7929d..00000000 --- a/bindings/ceylon-js/src/utils.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub fn set_panic_hook() { - // When the `console_error_panic_hook` feature is enabled, we can call the - // `set_panic_hook` function at least once during initialization, and then - // we will get better error messages if our code ever panics. - // - // For more details see - // https://github.com/rustwasm/console_error_panic_hook#readme - #[cfg(feature = "console_error_panic_hook")] - console_error_panic_hook::set_once(); -} diff --git a/bindings/ceylon-js/tests/web.rs b/bindings/ceylon-js/tests/web.rs deleted file mode 100644 index de5c1daf..00000000 --- a/bindings/ceylon-js/tests/web.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Test suite for the Web and headless browsers. - -#![cfg(target_arch = "wasm32")] - -extern crate wasm_bindgen_test; -use wasm_bindgen_test::*; - -wasm_bindgen_test_configure!(run_in_browser); - -#[wasm_bindgen_test] -fn pass() { - assert_eq!(1 + 1, 2); -} diff --git a/bindings/ceylon/ceylon/__core/agent/__init__.py b/bindings/ceylon/ceylon/__core/agent/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/ceylon/__core/agent/admin.py b/bindings/ceylon/ceylon/__core/agent/admin.py deleted file mode 100644 index bc9d7755..00000000 --- a/bindings/ceylon/ceylon/__core/agent/admin.py +++ /dev/null @@ -1,47 +0,0 @@ -import enum -import time -from typing import List - -from loguru import logger -from pydantic import BaseModel - -from .common import AgentCommon -from ceylon.ceylon import AgentDetail -from ceylon.core.admin import Admin - - -class AgentInfo(BaseModel): - id: str - name: str - role: str - connected_timestamp: float - - -class AgentDetails(BaseModel): - agents: List[AgentInfo] = [] - - -class CoreAdmin(Admin, AgentCommon): - def __init__(self, name, port, workers=None, server_mode=False): - if workers is None: - workers = [] - self.__server_mode = server_mode - self.__workers = workers - self.__connected_agents = [] - super().__init__(name, port) - AgentCommon.__init__(self) - - async def run(self, inputs: "bytes"): - logger.info((f"Admin on_run {self.details().id}", inputs)) - pass - - async def on_agent_connected(self, topic: "str", agent: AgentDetail): - # remove agent list has the same id or name - self.__connected_agents = [x for x in self.__connected_agents if x.id != agent.id] - self.__connected_agents = [x for x in self.__connected_agents if x.name != agent.name] - self.__connected_agents.append( - AgentInfo(id=agent.id, name=agent.name, role=agent.role, connected_timestamp=time.time())) - await self.broadcast_data(AgentDetails(agents=self.__connected_agents)) - - async def on_message(self, agent_id: "str", data: "bytes", time: "int"): - await self._on_message_handler(agent_id, data, time) diff --git a/bindings/ceylon/ceylon/__core/agent/agent.py b/bindings/ceylon/ceylon/__core/agent/agent.py deleted file mode 100644 index 82be90a9..00000000 --- a/bindings/ceylon/ceylon/__core/agent/agent.py +++ /dev/null @@ -1,29 +0,0 @@ -from ceylon.agent.common import AgentCommon -from ceylon.core.worker import Worker -from ceylon.static_val import DEFAULT_WORKSPACE_ID, DEFAULT_WORKSPACE_PORT, DEFAULT_WORKSPACE_IP, DEFAULT_CONF_FILE - - -class Agent(Worker, AgentCommon): - agent_type = "AGENT" - history_responses = [] - - def __init__(self, name="admin", - conf_file=DEFAULT_CONF_FILE, - workspace_id=DEFAULT_WORKSPACE_ID, - admin_port=DEFAULT_WORKSPACE_PORT, - admin_ip=DEFAULT_WORKSPACE_IP, - admin_peer="", - role="worker"): - super().__init__( - name=name, - workspace_id=workspace_id, - admin_port=admin_port, - admin_peer=admin_peer, - admin_ip=admin_ip, - role=role if role else name, - conf_file=conf_file - ) - AgentCommon.__init__(self) - - async def on_message(self, agent_id: "str", data: "bytes", time: "int"): - await self._on_message_handler(agent_id, data, time) diff --git a/bindings/ceylon/ceylon/__core/agent/agents.py b/bindings/ceylon/ceylon/__core/agent/agents.py deleted file mode 100644 index cfc7e223..00000000 --- a/bindings/ceylon/ceylon/__core/agent/agents.py +++ /dev/null @@ -1,117 +0,0 @@ -import copy -import pickle -from collections import deque -from typing import List - -from ceylon.agent.types.agent_request import AgentJobStepRequest, AgentJobResponse -from ceylon.agent.types.job import JobRequest, JobStatus -from ceylon.ceylon import AgentDetail -from ceylon.core.admin import Admin -from ceylon.core.worker import Worker - -from loguru import logger - -workspace_id = "ceylon_agent_stack" -admin_port = 8888 -admin_peer = "admin" - - -class Agent(Worker): - history_responses = [] - - def __init__(self, name: str, role: str): - super().__init__( - name=name, - workspace_id=workspace_id, - admin_port=admin_port, - admin_peer=admin_peer, - conf_file=None, - role=role - ) - - async def on_message(self, agent_id: "str", data: "bytes", time: "int"): - data = pickle.loads(data) - if type(data) == AgentJobStepRequest: - request: AgentJobStepRequest = data - if request.worker == self.details().name: - logger.debug(f"Agent process starting {self.details().name}") - response = await self.execute_request(request) - response.job_id = request.job_id - await self.broadcast(pickle.dumps(response)) - self.history_responses.append(response) - logger.debug(f"Agent process finished {self.details().name}") - elif type(data) == AgentJobResponse: - self.history_responses.append(data) - - async def execute_request(self, request: AgentJobStepRequest) -> AgentJobResponse: - raise NotImplemented - - -class RunnerAgent(Admin): - jobs: List[JobRequest] = [] - connected_agents: List[AgentDetail] = [] - server_mode = False - parallel_jobs = 1 - running_jobs = [] - - def __init__(self, name=workspace_id, port=admin_port, workers=[], tool_llm=None, server_mode=False, - parallel_jobs=1): - self.server_mode = server_mode - self.parallel_jobs = parallel_jobs - self.queue = deque() - self.llm = tool_llm - self.agent_responses = [] - self.workers = workers - super().__init__(name, port) - - async def run(self, inputs: "bytes"): - job = pickle.loads(inputs) - if type(job) == JobRequest: - await self.add_job(job) - - async def add_job(self, job: JobRequest): - job.initialize_graph() - self.jobs.append(job) - - async def start_job(self): - if len(self.running_jobs) < self.parallel_jobs: - for agent in self.connected_agents: - for job in self.jobs: - await job.on_agent_connected("", agent, self.broadcast) - self.running_jobs.append(job) - if len(self.running_jobs) == self.parallel_jobs: - return - - async def on_agent_connected(self, topic: "str", agent: AgentDetail): - self.connected_agents.append(agent) - await self.start_job() - - async def on_message(self, agent_id: "str", data: "bytes", time: "int"): - data = pickle.loads(data) - if type(data) == AgentJobResponse: - data: AgentJobResponse = data - job = self.get_job_by_id(data.job_id) - if job: - res = await job.execute_request(data, self.broadcast) - if res is not None and res.status == JobStatus.COMPLETED: - job_last = copy.deepcopy(job) - job_last.result = res - self.jobs.remove(job) - self.running_jobs.remove(job) - self.return_response = job_last - - await self.start_job() - if not self.server_mode: - if len(self.jobs) == 0: - await self.stop() - - def get_job_by_id(self, job_id: str): - for job in self.jobs: - if job.id == job_id: - return job - - def execute(self, job: JobRequest = None): - return self.run_admin(pickle.dumps(job or {}), self.workers) - - async def aexecute(self, job: JobRequest = None): - return await self.arun_admin(pickle.dumps(job or {}), self.workers) diff --git a/bindings/ceylon/ceylon/__core/agent/common.py b/bindings/ceylon/ceylon/__core/agent/common.py deleted file mode 100644 index 54b8ffaf..00000000 --- a/bindings/ceylon/ceylon/__core/agent/common.py +++ /dev/null @@ -1,66 +0,0 @@ -import inspect -import pickle -import traceback -from typing import Dict, Callable - -from loguru import logger - -message_handlers: Dict[str, Callable] = {} - - -def on_message(type): - def decorator(method): - class_name = method.__qualname__.split(".")[0] - method_key = f"{class_name}.{type}" - message_handlers[method_key] = method - - def wrapper(*args, **kwargs): - return method(*args, **kwargs) - - return wrapper - - return decorator - - -def has_param(func, param): - sig = inspect.signature(func) - params = list(sig.parameters.keys()) - return param in params - - -class AgentCommon: - - async def _on_message_handler(self, agent_id: "str", data: "bytes", time: "int"): - # Deserialize the message - try: - message = pickle.loads(data) - message_type = type(message) - - # Get the class hierarchy - class_hierarchy = inspect.getmro(self.__class__) - - # Find the most specific handler in the class hierarchy - handler = None - for cls in class_hierarchy: - class_name = cls.__name__ - method_key = f"{class_name}.{message_type}" - if method_key in message_handlers: - handler = message_handlers[method_key] - break - - # Trigger the appropriate handler if one is registered - if handler: - if has_param(handler, "agent_id") and has_param(handler, "time"): - await handler(self, message, agent_id=agent_id, time=time) - elif has_param(handler, "agent_id"): - await handler(self, message, agent_id=agent_id) - elif has_param(handler, "time"): - await handler(self, message, time=time) - else: - await handler(self, message) - else: - logger.debug(f"No handler registered in the class hierarchy for message type: {message_type}") - - except Exception as e: - # Full traceback - logger.error(traceback.format_exc()) diff --git a/bindings/ceylon/ceylon/__core/agent/types/__init__.py b/bindings/ceylon/ceylon/__core/agent/types/__init__.py deleted file mode 100644 index fef25052..00000000 --- a/bindings/ceylon/ceylon/__core/agent/types/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -from typing import List - -from pydantic.v1 import BaseModel, Field - - - - - -class LLMAgentResponse(BaseModel): - time: float - agent_id: str - agent_name: str - response: str - - -class LLMAgentRequest(BaseModel): - name: str - job_explanation: str - history: dict diff --git a/bindings/ceylon/ceylon/__core/agent/types/agent_request.py b/bindings/ceylon/ceylon/__core/agent/types/agent_request.py deleted file mode 100644 index 10616678..00000000 --- a/bindings/ceylon/ceylon/__core/agent/types/agent_request.py +++ /dev/null @@ -1,26 +0,0 @@ -import uuid -from typing import Any - -from pydantic import BaseModel, Field - -from .job_step import Step - - -class AgentJobStepRequest(BaseModel): - """ the agent job step request""" - id: str = Field(default_factory=lambda: str(uuid.uuid4()), alias='_id', description="the id of the request") - job_id: str = Field(None, description="the job id") - worker: str = Field(description="the worker name") - job_data: Any = Field(None, description="the job data") - step: Step = Field(None, description="the step") - - -class AgentJobResponse(BaseModel): - """ - the agent job response - this is the response that is sent back to the agent - """ - id: str = Field(default_factory=lambda: str(uuid.uuid4()), alias='_id', description="the id of the response") - job_id: str = Field(None, description="the job id of the response") - worker: str = Field(description="the worker name") - job_data: Any = Field(None, description="the job data") diff --git a/bindings/ceylon/ceylon/__core/agent/types/job.py b/bindings/ceylon/ceylon/__core/agent/types/job.py deleted file mode 100644 index ffa69dad..00000000 --- a/bindings/ceylon/ceylon/__core/agent/types/job.py +++ /dev/null @@ -1,129 +0,0 @@ -import enum -import pickle -import uuid -from collections import deque -from typing import List, Any, Optional, Callable, Awaitable - -import networkx as nx -from pydantic import BaseModel, Field, PrivateAttr - -from ceylon.agent.types.agent_request import AgentJobResponse, AgentJobStepRequest -from ceylon.ceylon import AgentDetail -from .job_step import Step - - - - -class JobSteps(BaseModel): - '''the steps of the job''' - id: str = Field(default_factory=lambda: str(uuid.uuid4()), alias='_id') - steps: List[Step] = Field(description="the steps of the job", default=[]) - - def step(self, worker: str): - '''get the next step of the job''' - for step in self.steps: - if step.worker == worker: - return step - return None - - -class JobStatus(enum.Enum): - IDLE = "IDLE" - RUNNING = "RUNNING" - COMPLETED = "COMPLETED" - FAILED = "FAILED" - CANCELLED = "CANCELLED" - - -class JobRequestResponse(BaseModel): - job_id: str = Field(None, description="the job id") - status: JobStatus = Field(JobStatus.RUNNING, description="the status of the job") - data: Any = Field(None, description="the data of the job") - - -class JobRequest(BaseModel): - title: str = Field(description="the name of the job") - id: str = Field(default_factory=lambda: str(uuid.uuid4()), alias='_id') - steps: JobSteps = Field(description="the steps of the job", default=JobSteps(steps=[])) - - on_success_callback: Optional[Callable[[JobRequestResponse, 'JobRequest'], Awaitable[None]]] = Field(default=None) - on_failure_callback: Optional[Callable[[JobRequestResponse, 'JobRequest'], Awaitable[None]]] = Field(default=None) - - current_status: JobStatus = Field(JobStatus.IDLE, description="the current status of the job") - - _network_graph: nx.DiGraph = PrivateAttr(default=nx.DiGraph()) - _network_graph_original: nx.DiGraph = PrivateAttr(default=nx.DiGraph()) - _queue: deque = PrivateAttr(default=deque([])) - - _agent_responses: List[AgentJobResponse] = PrivateAttr(default=[]) - - result: Any = Field(None, description="the result of the job") - job_data: Any = Field(None, description="the job data") - - class Config: - arbitrary_types_allowed = True - - def initialize_graph(self): - for step in self.steps.steps: - self._network_graph.add_node(step.worker) - for dep in step.dependencies: - self._network_graph.add_edge(dep, step.worker) - self._network_graph_original = self._network_graph.copy() - if not nx.is_directed_acyclic_graph(self._network_graph): - raise ValueError("Job steps contain cycles") - - for layer in nx.topological_generations(self._network_graph): - self._queue.append(layer) - - def get_next_agents(self): - if not self._queue: - return None - next_agents = self._queue[0] - # print(self.id, self.title - # , "Next agent is", next_agents) - return next_agents - - async def execute_request(self, data: AgentJobResponse = None, broadcaster=None): - if data: - self._agent_responses.append(data) - next_agents = self.get_next_agents() - for next_agent in next_agents: - if next_agent == data.worker: - next_agents.remove(next_agent) - if len(next_agents) == 0: - self._queue.popleft() - - next_agents = self.get_next_agents() - if next_agents: - for next_agent in next_agents: - # print(self.id, self.title, "Next agent", next_agent) - dependencies = list(self._network_graph_original.predecessors(next_agent)) - only_dependencies = {dt.worker: dt.job_data for dt in self._agent_responses if - dt.worker in dependencies} - if len(only_dependencies) == len(dependencies): - await broadcaster(pickle.dumps( - AgentJobStepRequest(worker=next_agent, job_data=self.job_data, job_id=self.id, - step=self.steps.step(next_agent)), - )) - else: - last_response = self._agent_responses[-1] - if self.on_success_callback: - await self.on_success_callback( - JobRequestResponse(job_id=self.id, status=JobStatus.COMPLETED, data=last_response.job_data), self) - self.result = last_response - return JobRequestResponse(job_id=self.id, status=JobStatus.COMPLETED, data=last_response.job_data) - - async def on_agent_connected(self, topic: "str", agent: AgentDetail, broadcaster=None): - next_agents = self.get_next_agents() - for next_agent in next_agents: - if next_agent == agent.name and self.current_status == JobStatus.IDLE: - self.current_status = JobStatus.RUNNING - await self.execute_request(None, broadcaster) - - def show_graph(self): - import matplotlib.pyplot as plt - nx.draw(self._network_graph, with_labels=True) - plt.show() - - def __str__(self): - return f"Job {self.id}: {self.title} with {len(self.steps.steps)} steps" diff --git a/bindings/ceylon/ceylon/__core/agent/types/job_step.py b/bindings/ceylon/ceylon/__core/agent/types/job_step.py deleted file mode 100644 index b6e8ce5f..00000000 --- a/bindings/ceylon/ceylon/__core/agent/types/job_step.py +++ /dev/null @@ -1,16 +0,0 @@ -import uuid -from typing import List - -from pydantic import BaseModel, Field - - -class Step(BaseModel): - '''the step''' - id: str = Field(default_factory=lambda: str(uuid.uuid4()), alias='_id') - worker: str = Field(description="the worker name of the step") - dependencies: List[str] = Field(description="the dependencies of the step, these steps must be another step worker", - default=[]) - explanation: str = Field(description="the explanation of the step", default="") - - class Config: - arbitrary_types_allowed = True diff --git a/bindings/ceylon/ceylon/__core/agents/__init__.py b/bindings/ceylon/ceylon/__core/agents/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/ceylon/__core/agents/worker_agent.py b/bindings/ceylon/ceylon/__core/agents/worker_agent.py deleted file mode 100644 index 7852c0a2..00000000 --- a/bindings/ceylon/ceylon/__core/agents/worker_agent.py +++ /dev/null @@ -1,265 +0,0 @@ -import asyncio -import time -from abc import ABC, abstractmethod -from dataclasses import dataclass -from typing import List, Optional - - -# Ceylon namespace implementation -class Ceylon: - - @staticmethod - def version() -> str: - return "1.0.0" - - @staticmethod - def enable_log(level: str) -> None: - # Implement logging configuration - import logging - logging.basicConfig(level=level.upper()) - - @staticmethod - def cprint(message: str) -> None: - print(f"[Ceylon] {message}") - -# Data classes for configuration -@dataclass -class AdminAgentConfig: - name: str - port: int - -@dataclass -class WorkerAgentConfig: - name: str - conf_file: Optional[str] - work_space_id: str - admin_peer: str - role: str - admin_port: int - admin_ip: str - - def __post_init__(self): - self.conf_file = self.conf_file or ".ceylon_network" - -@dataclass -class AgentDetail: - name: str - id: str - role: str - -# Abstract base classes for handlers -class MessageHandler(ABC): - @abstractmethod - async def on_message(self, agent_id: str, data: bytes, time: int) -> None: - pass - -class Processor(ABC): - @abstractmethod - async def run(self, inputs: bytes) -> None: - pass - -class EventHandler(ABC): - @abstractmethod - async def on_agent_connected(self, topic: str, agent: AgentDetail) -> None: - pass - -# Base Agent class with common functionality -class BaseAgent: - def __init__(self, message_handler: MessageHandler, processor: Processor, event_handler: EventHandler): - self.message_handler = message_handler - self.processor = processor - self.event_handler = event_handler - self.running = False - self._agent_detail = None - - async def _handle_message(self, agent_id: str, data: bytes): - await self.message_handler.on_message(agent_id, data, int(time.time())) - - async def broadcast(self, message: bytes): - raise NotImplementedError() - - def details(self) -> AgentDetail: - return self._agent_detail - -# AdminAgent implementation -class AdminAgent(BaseAgent): - def __init__(self, config: AdminAgentConfig, message_handler: MessageHandler, - processor: Processor, event_handler: EventHandler): - super().__init__(message_handler, processor, event_handler) - self.config = config - self._agent_detail = AgentDetail( - name=config.name, - id=f"admin_{config.name}_{config.port}", - role="admin" - ) - self.workers: List[WorkerAgent] = [] - - async def start(self, inputs: bytes, workers: List['WorkerAgent']): - if self.running: - return - - self.workers = workers - self.running = True - - # Process inputs - await self.processor.run(inputs) - - # Start listening for messages - await self._start_message_handler() - - Ceylon.cprint(f"AdminAgent {self.config.name} started on port {self.config.port}") - - async def stop(self): - if not self.running: - return - - self.running = False - # Cleanup and stop message handling - await self._cleanup() - - Ceylon.cprint(f"AdminAgent {self.config.name} stopped") - - async def broadcast(self, message: bytes): - if not self.running: - return - - # Broadcast message to all workers - for worker in self.workers: - try: - await worker._handle_message(self._agent_detail.id, message) - except Exception as e: - Ceylon.cprint(f"Error broadcasting to worker {worker.details().id}: {e}") - - async def _start_message_handler(self): - # Implementation for message handling setup - pass - - async def _cleanup(self): - # Cleanup resources - pass - -# WorkerAgent implementation -class WorkerAgent(BaseAgent): - def __init__(self, config: WorkerAgentConfig, message_handler: MessageHandler, - processor: Processor, event_handler: EventHandler): - super().__init__(message_handler, processor, event_handler) - self.config = config - self._agent_detail = AgentDetail( - name=config.name, - id=f"worker_{config.name}_{config.work_space_id}", - role=config.role - ) - self._admin_connection = None - - async def start(self, inputs: bytes): - if self.running: - return - - self.running = True - - # Connect to admin - await self._connect_to_admin() - - # Process inputs - await self.processor.run(inputs) - - # Start listening for messages - await self._start_message_handler() - - Ceylon.cprint(f"WorkerAgent {self.config.name} started and connected to admin") - - async def stop(self): - if not self.running: - return - - self.running = False - # Cleanup and stop message handling - await self._cleanup() - - Ceylon.cprint(f"WorkerAgent {self.config.name} stopped") - - async def broadcast(self, message: bytes): - if not self.running or not self._admin_connection: - return - - # Send message to admin - try: - # Implementation for sending message to admin - await self._send_to_admin(message) - except Exception as e: - Ceylon.cprint(f"Error broadcasting from worker {self._agent_detail.id}: {e}") - - async def _connect_to_admin(self): - # Implementation for connecting to admin agent - pass - - async def _start_message_handler(self): - # Implementation for message handling setup - pass - - async def _cleanup(self): - # Cleanup resources - pass - - async def _send_to_admin(self, message: bytes): - # Implementation for sending message to admin - pass - -# Example implementation of handlers -class DefaultMessageHandler(MessageHandler): - async def on_message(self, agent_id: str, data: bytes, time: int) -> None: - Ceylon.cprint(f"Received message from {agent_id} at {time}: {data.decode()}") - -class DefaultProcessor(Processor): - async def run(self, inputs: bytes) -> None: - Ceylon.cprint(f"Processing inputs: {inputs.decode()}") - -class DefaultEventHandler(EventHandler): - async def on_agent_connected(self, topic: str, agent: AgentDetail) -> None: - Ceylon.cprint(f"Agent {agent.id} connected to topic {topic}") - -# Example usage: -async def main(): - # Create handlers - message_handler = DefaultMessageHandler() - processor = DefaultProcessor() - event_handler = DefaultEventHandler() - - # Create admin agent - admin_config = AdminAgentConfig(name="admin1", port=8000) - admin_agent = AdminAgent(admin_config, message_handler, processor, event_handler) - - # Create worker agents - worker_configs = [ - WorkerAgentConfig( - name="worker1", - conf_file=None, - work_space_id="ws1", - admin_peer="admin1", - role="worker", - admin_port=8000, - admin_ip="localhost" - ) - ] - - workers = [ - WorkerAgent(config, message_handler, processor, event_handler) - for config in worker_configs - ] - - # Start agents - await admin_agent.start(b"admin_inputs", workers) - for worker in workers: - await worker.start(b"worker_inputs") - - # Example broadcast - await admin_agent.broadcast(b"Hello from admin!") - await workers[0].broadcast(b"Hello from worker!") - - # Stop agents - await admin_agent.stop() - for worker in workers: - await worker.stop() - -if __name__ == "__main__": - asyncio.run(main()) \ No newline at end of file diff --git a/bindings/ceylon/ceylon/__core/auto/__init__.py b/bindings/ceylon/ceylon/__core/auto/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/ceylon/__core/auto/manager/__init__.py b/bindings/ceylon/ceylon/__core/auto/manager/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/ceylon/__core/auto/manager/abstract_manager.py b/bindings/ceylon/ceylon/__core/auto/manager/abstract_manager.py deleted file mode 100644 index a74f2b7d..00000000 --- a/bindings/ceylon/ceylon/__core/auto/manager/abstract_manager.py +++ /dev/null @@ -1,36 +0,0 @@ -from abc import ABC, abstractmethod - - -# Abstract TaskManager class -class TaskManager(ABC): - def __init__(self): - self.tasks = [] - - def add_task(self, task): - """Add a Task to the manager.""" - self.tasks.append(task) - - def remove_task(self, task): - """Remove a Task from the manager.""" - self.tasks.remove(task) - - def all_tasks_completed(self): - """Check if all tasks are completed.""" - return all(task.all_subtasks_completed() for task in self.tasks) - - def progress_tasks(self): - """Progress through the tasks by simulating subtask progression.""" - for task in self.tasks: - print(f"Progressing Task: '{task.name}'") - subtasks_sequence = task.subtasks # Assuming tasks have subtasks in desired order - for subtask in subtasks_sequence: - if subtask.state in ['pending', 'approved', 'failed']: - self.progress_subtask(subtask) - print("\n") - if self.all_tasks_completed(): - print("All tasks are completed.") - - @abstractmethod - def progress_subtask(self, subtask): - """Simulate the progression of a subtask.""" - pass diff --git a/bindings/ceylon/ceylon/__core/auto/manager/agent_taskmanager.py b/bindings/ceylon/ceylon/__core/auto/manager/agent_taskmanager.py deleted file mode 100644 index 44db2b9c..00000000 --- a/bindings/ceylon/ceylon/__core/auto/manager/agent_taskmanager.py +++ /dev/null @@ -1,23 +0,0 @@ -from ceylon import CoreAdmin -from ceylon.static_val import DEFAULT_WORKSPACE_ID, DEFAULT_WORKSPACE_PORT - - -class AgentTaskManager(CoreAdmin): - name = DEFAULT_WORKSPACE_ID - - def __init__(self, name=DEFAULT_WORKSPACE_ID, - port=DEFAULT_WORKSPACE_PORT, - *args, - **kwargs): - self.name = name - self.agents = [] - super().__init__(name=name, port=port, *args, **kwargs) - - def register_agent(self, agent): - self.agents.append(agent) - - def do(self, inputs: bytes = b''): - self.run_admin(inputs, self.agents) - - async def async_do(self, inputs: bytes = b''): - await self.arun_admin(inputs, self.agents) diff --git a/bindings/ceylon/ceylon/__core/auto/manager/cli_manager.py b/bindings/ceylon/ceylon/__core/auto/manager/cli_manager.py deleted file mode 100644 index 3ae5f6be..00000000 --- a/bindings/ceylon/ceylon/__core/auto/manager/cli_manager.py +++ /dev/null @@ -1,48 +0,0 @@ -from ceylon.auto.manager.abstract_manager import TaskManager - - -class CLI_TaskManager(TaskManager): - def progress_subtask(self, subtask): - # Approve if needed - if subtask.needs_approval and subtask.state == 'pending': - user_input = input(f"SubTask '{subtask.name}' needs approval. Approve? (y/n): ") - if user_input.lower() == 'y': - subtask.approve() - print(f"SubTask '{subtask.name}' approved.") - else: - print(f"SubTask '{subtask.name}' not approved.") - return - - # Collect required inputs if not yet provided - if subtask.inputs_needed and not subtask.has_all_inputs(): - print(f"SubTask '{subtask.name}' requires additional inputs.") - for input_name in subtask.inputs_needed: - if input_name not in subtask.inputs_provided: - input_value = input(f"Please provide input '{input_name}': ") - subtask.inputs_provided[input_name] = input_value - - # Handle failed state and retries - if subtask.state == 'failed' and subtask.can_retry(): - user_input = input(f"SubTask '{subtask.name}' failed. Retry? (y/n): ") - if user_input.lower() == 'y': - subtask.retry() - print(f"Retrying SubTask '{subtask.name}'.") - else: - print(f"SubTask '{subtask.name}' will not be retried.") - return - - # Start subtask if possible - if subtask.can_start() and subtask.state in ['approved', 'pending']: - subtask.start() - print(f"SubTask '{subtask.name}' started by {subtask.executor}.") - # Simulate completion or failure - user_input = input(f"Did SubTask '{subtask.name}' complete successfully? (y/n): ") - if user_input.lower() == 'y': - subtask.complete() - print(f"SubTask '{subtask.name}' completed.") - else: - subtask.fail() - print(f"SubTask '{subtask.name}' failed.") - else: - if subtask.state not in ['completed', 'in_progress', 'failed']: - print(f"SubTask '{subtask.name}' cannot start yet. Waiting for dependencies or inputs.") diff --git a/bindings/ceylon/ceylon/__core/auto/model.py b/bindings/ceylon/ceylon/__core/auto/model.py deleted file mode 100644 index 6d71a216..00000000 --- a/bindings/ceylon/ceylon/__core/auto/model.py +++ /dev/null @@ -1,75 +0,0 @@ -from dataclasses import field, dataclass -from typing import Any, Dict, List -from uuid import uuid4 - -from pydantic import BaseModel -from transitions import Machine, State - - -@dataclass -class SubTask: - name: str - executor: str - needs_approval: bool - dependencies: List['SubTask'] = field(default_factory=list) - retry_count: int = 0 - max_retries: int = 2 - state: str = 'pending' - inputs_needed: List[str] = field(default_factory=list) - inputs_provided: Dict[str, Any] = field(default_factory=dict) - id: str = field(default_factory=lambda: str(uuid4())) - - states = [ - State(name='pending'), - State(name='approved'), - State(name='in_progress'), - State(name='completed'), - State(name='failed') - ] - - transitions = [ - {'trigger': 'approve', 'source': 'pending', 'dest': 'approved', 'conditions': 'needs_approval'}, - {'trigger': 'start', 'source': ['approved', 'pending'], 'dest': 'in_progress', 'conditions': 'can_start'}, - {'trigger': 'complete', 'source': 'in_progress', 'dest': 'completed'}, - {'trigger': 'fail', 'source': 'in_progress', 'dest': 'failed', 'after': 'handle_failure'}, - {'trigger': 'retry', 'source': 'failed', 'dest': 'in_progress', 'conditions': 'can_retry'}, - ] - - def __post_init__(self): - self.machine = Machine( - model=self, - states=SubTask.states, - transitions=SubTask.transitions, - initial=self.state - ) - - def can_start(self): - dependencies_completed = all(dep.state == 'completed' for dep in self.dependencies) - return dependencies_completed and self.has_all_inputs() - - def has_all_inputs(self): - return all(input_name in self.inputs_provided for input_name in self.inputs_needed) - - def can_retry(self): - return self.retry_count < self.max_retries - - def handle_failure(self): - self.retry_count += 1 - print(f"SubTask '{self.name}' failed. Retry count: {self.retry_count}") - - -@dataclass -class Task: - name: str - subtasks: List[SubTask] = field(default_factory=list) - id: str = field(default_factory=lambda: str(uuid4())) - - def all_subtasks_completed(self): - return all(subtask.state == 'completed' for subtask in self.subtasks) - - -class SubTaskRequest(BaseModel): - task_id: str # id of the parent task - subtask_name: str # name of the sub task - inputs: Dict[str, Any] # inputs provided by the user - dependencies: List[str] # list of sub task names diff --git a/bindings/ceylon/ceylon/__core/auto/worker/__init__.py b/bindings/ceylon/ceylon/__core/auto/worker/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/ceylon/__core/auto/worker/agent_executor.py b/bindings/ceylon/ceylon/__core/auto/worker/agent_executor.py deleted file mode 100644 index 939843e7..00000000 --- a/bindings/ceylon/ceylon/__core/auto/worker/agent_executor.py +++ /dev/null @@ -1,29 +0,0 @@ -from loguru import logger - -from ceylon import Agent, on_message -from ceylon.agent.admin import AgentDetails -from ceylon.auto.model import SubTaskRequest -from ceylon.static_val import DEFAULT_WORKSPACE_ID, DEFAULT_WORKSPACE_PORT, DEFAULT_WORKSPACE_IP - - -class TaskExecutorAgent(Agent): - - def __init__(self, name: str, role: str, - conf_file=None, - workspace_id: str = DEFAULT_WORKSPACE_ID, - admin_port: int = DEFAULT_WORKSPACE_PORT, - admin_ip: str = DEFAULT_WORKSPACE_IP, - *args, - **kwargs): - super().__init__(name=name, role=role, workspace_id=workspace_id, admin_port=admin_port, admin_ip=admin_ip, - conf_file=conf_file, - *args, **kwargs) - - @on_message(AgentDetails) - async def on_agent_details(self, data: AgentDetails): - pass - # logger.info(data) - - @on_message(SubTaskRequest) - async def on_sub_task_request(self, sub_task_request): - logger.info(sub_task_request) diff --git a/bindings/ceylon/ceylon/__core/core/__init__.py b/bindings/ceylon/ceylon/__core/core/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/ceylon/__core/core/admin.py b/bindings/ceylon/ceylon/__core/core/admin.py deleted file mode 100644 index 1d831da5..00000000 --- a/bindings/ceylon/ceylon/__core/core/admin.py +++ /dev/null @@ -1,57 +0,0 @@ -import asyncio -import pickle -from typing import Any - -from ceylon.ceylon import AdminAgent, AdminAgentConfig, Processor, MessageHandler, EventHandler, AgentDetail -from ceylon.ceylon.ceylon import uniffi_set_event_loop - - -class Admin(AdminAgent, Processor, MessageHandler, EventHandler): - - def __init__(self, name="admin", port=8888): - self.return_response = None - super().__init__(config=AdminAgentConfig(name=name, port=port), processor=self, on_message=self, on_event=self) - - async def run(self, inputs: "bytes"): - pass - - # - async def on_message(self, agent_id: "str", data: "bytes", time: "int"): - pass - - def run_admin(self, inputs: bytes, workers): - import asyncio - - try: - # Try to get the running event loop - event_loop = asyncio.get_running_loop() - except RuntimeError: - # No running event loop, create a new one - event_loop = asyncio.new_event_loop() - asyncio.set_event_loop(event_loop) - return event_loop.run_until_complete(self.arun_admin(inputs, workers)) - - # If the loop is already running, schedule the coroutine in the running loop - if event_loop.is_running(): - # Create a future to run the coroutine - future = asyncio.ensure_future(self.arun_admin(inputs, workers), loop=event_loop) - return event_loop.run_until_complete(future) - else: - # If no loop is running, run the coroutine with asyncio.run() - return asyncio.run(self.arun_admin(inputs, workers)) - - async def arun_admin(self, inputs: "bytes", workers): - uniffi_set_event_loop(asyncio.get_event_loop()) - await self.start(inputs, workers) - return self.return_response - - # - - async def execute_task(self, input): - pass - - async def on_agent_connected(self, topic: "str", agent_id: AgentDetail): - pass - - async def broadcast_data(self, message: Any): - await self.broadcast(pickle.dumps(message)) diff --git a/bindings/ceylon/ceylon/__core/core/worker.py b/bindings/ceylon/ceylon/__core/core/worker.py deleted file mode 100644 index 8c57b600..00000000 --- a/bindings/ceylon/ceylon/__core/core/worker.py +++ /dev/null @@ -1,65 +0,0 @@ -import asyncio -import pickle -from typing import Any - -from ceylon.ceylon import WorkerAgent, WorkerAgentConfig, Processor, \ - MessageHandler, EventHandler - -from ceylon.ceylon.ceylon import uniffi_set_event_loop -from ceylon.static_val import DEFAULT_WORKSPACE_PORT, DEFAULT_WORKSPACE_ID, DEFAULT_WORKSPACE_IP, DEFAULT_CONF_FILE - - -class Worker(WorkerAgent, Processor, MessageHandler, EventHandler): - agent_type = "WORKER" - - def __init__(self, name="admin", - workspace_id=DEFAULT_WORKSPACE_ID, - conf_file=DEFAULT_CONF_FILE, - admin_peer="", - admin_port=DEFAULT_WORKSPACE_PORT, - role="worker", - admin_ip=DEFAULT_WORKSPACE_IP): - super().__init__(config=WorkerAgentConfig(name=name, - role=role, - conf_file=conf_file, - admin_peer=admin_peer, - admin_port=admin_port, - work_space_id=workspace_id, admin_ip=admin_ip), processor=self, - on_message=self, on_event=self) - - async def run(self, inputs: "bytes"): - pass - - async def on_message(self, agent_id: "str", data: "bytes", time: "int"): - pass - - def run_worker(self, inputs: bytes): - import asyncio - - try: - # Try to get the running event loop - event_loop = asyncio.get_running_loop() - except RuntimeError: - # No running event loop, create a new one - event_loop = asyncio.new_event_loop() - asyncio.set_event_loop(event_loop) - return event_loop.run_until_complete(self.arun_worker(inputs)) - - # If the loop is already running, schedule the coroutine in the running loop - if event_loop.is_running(): - # Create a future to run the coroutine - future = asyncio.ensure_future(self.arun_worker(inputs), loop=event_loop) - return event_loop.run_until_complete(future) - else: - # If no loop is running, run the coroutine with asyncio.run() - return asyncio.run(self.arun_worker(inputs)) - - async def arun_worker(self, inputs: "bytes"): - uniffi_set_event_loop(asyncio.get_event_loop()) - await self.start(inputs) - - async def on_agent_connected(self, topic: "str", agent: "AgentDetail"): - pass - - async def broadcast_data(self, message: Any): - await self.broadcast(pickle.dumps(message)) diff --git a/bindings/ceylon/ceylon/__core/in/__init__.py b/bindings/ceylon/ceylon/__core/in/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/ceylon/__core/llm/__init__.py b/bindings/ceylon/ceylon/__core/llm/__init__.py deleted file mode 100644 index b003dc6c..00000000 --- a/bindings/ceylon/ceylon/__core/llm/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .llm_task_coordinator import LLMTaskCoordinator -from .llm_task_operator import LLMTaskOperator diff --git a/bindings/ceylon/ceylon/__core/llm/llm/__init__.py b/bindings/ceylon/ceylon/__core/llm/llm/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/ceylon/__core/llm/llm/llm_executor.py b/bindings/ceylon/ceylon/__core/llm/llm/llm_executor.py deleted file mode 100644 index 6f5d0764..00000000 --- a/bindings/ceylon/ceylon/__core/llm/llm/llm_executor.py +++ /dev/null @@ -1,60 +0,0 @@ -from copy import copy as shallow_copy -from typing import Any - -import langchain_core -import pydantic -from langchain.agents import AgentExecutor -from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser -from langchain_core.utils.function_calling import format_tool_to_openai_function -from pydantic import BaseModel, Field - -from ceylon.llm.prompt import PromptWrapper - - -class LLMExecutor(BaseModel): - llm: Any = Field( - default=None, description="Language model that will be used to execute the job" - ) - type: str = Field( - default="llm_executor", description="The type of the executor" - ) - - def execute(self, prompt_wrapper: PromptWrapper, tools: list = []): - - if tools and len(tools) > 0: - execution_llm = shallow_copy(self.llm).bind( - functions=[langchain_core.utils.function_calling.convert_to_openai_function(t) for t in tools] - ) - # return self.tool_calling(prompt_wrapper, tools) - else: - execution_llm = shallow_copy(self.llm) - - prompt = prompt_wrapper.template - if prompt_wrapper.parser is not None: - try: - prompt_and_model = prompt | execution_llm | prompt_wrapper.parser - output = prompt_and_model.invoke({ - **prompt_wrapper.arguments, - }) - return output - except pydantic.ValidationError as e: - print(f"Parsing error: {e}") - # Handle the error appropriately - return None # or a default JobSteps object - else: - prompt_and_model = prompt | execution_llm - output = prompt_and_model.invoke({ - **prompt_wrapper.arguments, - }) - return output.content - - def tool_calling(self, prompt_wrapper: PromptWrapper, tools: list): - prompt = prompt_wrapper.template - execution_llm = shallow_copy(self.llm) - llm = execution_llm.bind( - functions=[langchain_core.utils.function_calling.convert_to_openai_function(t) for t in tools]) - agent = prompt | llm | OpenAIFunctionsAgentOutputParser() - executor = AgentExecutor(agent=agent, tools=tools, verbose=True, max_iterations=10, - return_intermediate_steps=True) - llm_response = executor.invoke({**prompt_wrapper.arguments, }) - return llm_response["output"] diff --git a/bindings/ceylon/ceylon/__core/llm/llm_task_coordinator.py b/bindings/ceylon/ceylon/__core/llm/llm_task_coordinator.py deleted file mode 100644 index 64c4da24..00000000 --- a/bindings/ceylon/ceylon/__core/llm/llm_task_coordinator.py +++ /dev/null @@ -1,400 +0,0 @@ -import copy -import logging -import sys -from textwrap import dedent -from typing import Dict, List, Set - -import networkx as nx -import pydantic.v1 -from langchain_core.output_parsers import StrOutputParser, PydanticOutputParser -from langchain_core.prompts import ChatPromptTemplate, PromptTemplate -from loguru import logger - -from ceylon.llm.llm_task_operator import LLMTaskOperator -from ceylon.static_val import DEFAULT_WORKSPACE_ID, DEFAULT_WORKSPACE_PORT -from ceylon.task import SubTaskResult, Task, SubTask -from ceylon.task.task_coordinator import TaskCoordinator -from ceylon.task.task_operation import TaskDeliverable - -logger.remove() -logger.add(sys.stderr, level="INFO") - - -class TaskDeliverableModel(pydantic.v1.BaseModel): - objective: str = pydantic.v1.Field( - description="The main objective of the task", - default="" - ) - deliverable: str = pydantic.v1.Field( - description="The single, primary deliverable for the task", - default="" - ) - key_features: List[str] = pydantic.v1.Field( - description="Key features of the deliverable", - default=[] - ) - considerations: List[str] = pydantic.v1.Field( - description="Important considerations or constraints for the deliverable", - default=[] - ) - - def to_v2(self) -> TaskDeliverable: - return TaskDeliverable( - objective=self.objective, - deliverable=self.deliverable, - key_features=self.key_features, - considerations=self.considerations - ) - - @staticmethod - def create_default_task_deliverable(task): - return TaskDeliverableModel( - objective="Complete the assigned task", - deliverable=task.description, - key_features=["Basic functionality"], - considerations=["Meet minimum requirements"] - ) - - -class SubTaskModel(pydantic.v1.BaseModel): - name: str = pydantic.v1.Field(description="Subtask name (snake_case)") - description: str = pydantic.v1.Field(description="Detailed subtask explanation", default="") - required_specialty: str = pydantic.v1.Field(description="Required skill or expertise", default="") - depends_on: Set[str] = pydantic.v1.Field(description="Names of prerequisite subtasks", default=[]) - expected_output: str = pydantic.v1.Field(description="Expected output of the subtask", default="") - - def to_v2(self, parent_task_id) -> SubTask: - return SubTask( - parent_task_id=parent_task_id, - name=self.name, - description=self.description, - required_specialty=self.required_specialty, - depends_on=self.depends_on, - expected_output=self.expected_output - ) - - -class SubTaskListSchema(pydantic.v1.BaseModel): - sub_task_list: List[SubTaskModel] = pydantic.v1.Field(description="The subtasks of the task", default_factory=list) - - -class LLMTaskCoordinator(TaskCoordinator): - tasks: List[Task] = [] - agents: List[LLMTaskOperator] = [] - results: Dict[str, List[SubTaskResult]] = {} - team_network: nx.Graph = nx.Graph() - - def __init__(self, tasks: List[Task] = None, agents: List[LLMTaskOperator] = None, - context: str = "", - team_goal: str = "", - - llm=None, tool_llm=None, - name=DEFAULT_WORKSPACE_ID, - port=DEFAULT_WORKSPACE_PORT): - self.context = context - self.team_goal = team_goal - self.llm = copy.copy(llm) - self.tool_llm = copy.copy(tool_llm) if tool_llm is not None else copy.copy(llm) - self.tasks = tasks if tasks is not None else [] - self.agents = agents if agents is not None else [] - super().__init__(name=name, port=port, tasks=tasks, agents=agents) - - def on_init(self): - if len(self.agents) > 0: - logger.info( - f"LLM Task Coordinator initialized with {len(self.tasks)} " - f"tasks and {len(self.get_llm_operators)} agents {[agent.details().name for agent in self.get_llm_operators]}") - - async def update_task(self, idx: int, task: Task): - logger.info(f"Updating task {task.name} with {len(task.subtasks)} subtasks") - if task.task_deliverable is None: - task_deliverable = await self.build_task_deliverable(task) - task.set_deliverable(task_deliverable) - - if len(task.subtasks) == 0: - sub_tasks = await self.generate_tasks_from_description(task) - for sub_task in sub_tasks: - task.add_subtask(sub_task) - - final_sub_task = await self.generate_final_sub_task_from_description(task) - task.add_subtask(final_sub_task) - - logger.info(f"Task {task.name} updated with {len(task.subtasks)} subtasks") - for subtask in task.subtasks.values(): - logger.info(f"Subtask {subtask.name} updated with {len(subtask.depends_on)} dependencies") - # await self.update_team_network(task) - return task - - async def get_task_executor(self, task: SubTask) -> str: - return await self.get_best_agent_for_subtask(task) - - @property - def get_llm_operators(self) -> List[LLMTaskOperator]: - operators = [] - for agent in self.agents: - if isinstance(agent, LLMTaskOperator) and hasattr(agent, - "agent_type") and agent.agent_type == LLMTaskOperator.agent_type: - operators.append(agent) - - return operators - - async def get_best_agent_for_subtask(self, subtask: SubTask) -> str: - logger.debug(f"Getting best agent for subtask '{subtask.name}'") - agent_specialties = "\n".join( - [f"{agent.details().name}: {agent.details().role} {agent.context}" for agent in self.get_llm_operators]) - - prompt_template = ChatPromptTemplate.from_template( - """ - Select the most suitable agent for this subtask: - - Subtask: {subtask_description} - Required specialty: {required_specialty} - Expected output: {expected_output} - - Agent specialties: - {agent_specialties} - - Available agents: {agent_names} - - Important: Respond ONLY with the exact name of the single most suitable agent from the available agents list. - If no agent perfectly matches, choose the closest fit. - """ - ) - - runnable = prompt_template | self.llm | StrOutputParser() - - def get_valid_agent_name(max_attempts=3): - agent_names = [agent.details().name for agent in self.get_llm_operators] - - for attempt in range(max_attempts): - response = runnable.invoke({ - "subtask_description": subtask.description, - "expected_output": subtask.expected_output, - "required_specialty": subtask.required_specialty, - "agent_specialties": agent_specialties, - "agent_names": ", ".join(agent_names) - }).strip() - - if response in agent_names: - return response - logger.info(f"Attempt {attempt + 1}: Invalid agent name received: {response} {subtask}. Retrying...") - - raise Exception(f"Failed to get a valid agent name after {max_attempts} attempts.") - - return get_valid_agent_name() - - async def generate_final_sub_task_from_description(self, task: Task) -> SubTask: - logger.debug( - f"Generating final subtask from task description '{task.description}' and subtasks '{len(task.subtasks)}'") - pydantic_parser = PydanticOutputParser(pydantic_object=SubTaskModel) - format_instructions = pydantic_parser.get_format_instructions() - # Prompt template - prompt = PromptTemplate( - template=dedent( - """ - Given the following job description and existing subtasks, add a final delivery step to complete the project. - This final step should focus on delivering the completed work. - - Job Description: {description} - Job Deliverable Data: {task_deliverable} - - Existing Subtasks: - {existing_subtasks} - - Respond with the final delivery step in the following JSON format: - - {format_instructions} - - Additional Considerations: - - Ensure the final step encompasses presenting or delivering the completed work - - Use clear, action-oriented language for the description - - Include dependencies on relevant existing subtasks - - Focus on delivering the functionality and value of the completed project - """ - ), - input_variables=["description", "task_deliverable", "existing_subtasks"], - partial_variables={"format_instructions": format_instructions}, - ) - prompt_str = prompt.format(**{ - "description": task.description, - "task_deliverable": task.task_deliverable, - "existing_subtasks": "\n".join([f"{t.name}- {t.description}" for t in task.subtasks.values()]) - }) - logger.opt(exception=True).debug(f"Prompt: {prompt_str}") - - chain = prompt | self.tool_llm | pydantic_parser - final_subtask_model = chain.invoke(input={ - "description": task.description, - "task_deliverable": task.task_deliverable, - "existing_subtasks": "\n".join([f"{t.name}- {t.description}" for t in task.subtasks.values()]) - }) - print(f"Final subtask: {final_subtask_model}") - return final_subtask_model.to_v2(task.id) - - async def generate_tasks_from_description(self, task: Task) -> List[SubTask]: - logger.info(f"Generating sub tasks from description: {task.description}") - - pydantic_parser = PydanticOutputParser(pydantic_object=SubTaskListSchema) - format_instructions = pydantic_parser.get_format_instructions() - - # Prompt template - prompt = PromptTemplate( - template=dedent( - """ - Analyze the following job description and break it down into a main task and 3-5 key subtasks: - - Job Description: {description} - Job Deliverable: {task_deliverable} - - {format_instructions} - - Guidelines: - - Max {number_of_max_tasks} subtasks - - Name must be in snake_case - - Description must be in clear, action-oriented language - - Prioritize subtasks by importance or sequence - - Ensure each subtask is distinct and essential - - Use clear, action-oriented language - - Include subtask interdependencies where relevant - - Strictly adhere to the JSON format provided above - """ - ), - input_variables=["description", "task_deliverable", "number_of_max_tasks"], - partial_variables={"format_instructions": format_instructions}, - ) - - prompt_str = prompt.format(**{ - "description": task.description, - "metadata": task.metadata, - "task_deliverable": task.task_deliverable, - "number_of_max_tasks": task.max_subtasks - 1, - }) - logger.opt(exception=True).debug(f"Prompt: {prompt_str}") - - chain = prompt | self.tool_llm | pydantic_parser - sub_task_list = chain.invoke(input={ - "description": task.description, - "metadata": task.metadata, - "task_deliverable": task.task_deliverable, - "number_of_max_tasks": task.max_subtasks - 1, - }) - - # logger.info(sub_task_list) - # Make sure subtasks are valid - sub_task_list = self.recheck_and_update_subtasks(subtasks=sub_task_list) - if len(sub_task_list) == 0: - return [] - return [t.to_v2(task.id) for t in sub_task_list] - - def recheck_and_update_subtasks(self, subtasks): - - pydantic_parser = PydanticOutputParser(pydantic_object=SubTaskListSchema) - format_instructions = pydantic_parser.get_format_instructions() - - # Prompt template - prompt = PromptTemplate( - template=dedent( - """ - You are tasked with reviewing and modifying a list of SubTasks. Please process the following list of SubTasks according to these criteria: - - 1. Name Format: - - Convert all SubTask names to snake_case format. - - Ensure each word is lowercase and separated by underscores. - - Example: "draftArticleOutline" should become "draft_article_outline" - - 2. Dependency Validation: - - Check that all dependencies listed in the 'depends_on' field are valid SubTask names within the list. - - Ensure that the dependency names are also in snake_case format. - - Remove any dependencies that do not correspond to existing SubTask names. - - 3. Circular Dependency Check: - - Verify that there are no circular dependencies among the SubTasks. - - A circular dependency occurs when Task A depends on Task B, and Task B directly or indirectly depends on Task A. - - 4. Consistency: - - Ensure all other fields (id, parent_task_id, description, required_specialty, completed, completed_at, result) remain unchanged. - - 5. Output Format: - - Return the modified list of SubTasks in the same structure as the input. - - Here is the list of SubTasks to process: - - {subtasks} - - Please provide the updated list of SubTasks with all the above modifications and validations applied. - Output in JSON format: - - {format_instructions} - - Guidelines: - - Name must be in snake_case - - Description must be in clear, action-oriented language - - Prioritize subtasks by importance or sequence - - Ensure each subtask is distinct and essential - - Use clear, action-oriented language - - Include subtask interdependencies where relevant - - Strictly adhere to the JSON format provided above - """ - ), - input_variables=["subtasks"], - partial_variables={"format_instructions": format_instructions}, - ) - - # Chain - prompt_str = prompt.format(**{ - "subtasks": subtasks - }) - logger.opt(exception=True).debug(f"Prompt: {prompt_str}") - - chain = prompt | self.tool_llm | pydantic_parser - result: SubTaskListSchema = chain.invoke(input={ - "subtasks": subtasks - }) - if result is None: - return [] - return result.sub_task_list - - async def build_task_deliverable(self, task: Task): - logger.info(f"Building deliverable for task: {task.id}") - - pydantic_parser = PydanticOutputParser(pydantic_object=TaskDeliverableModel) - format_instructions = pydantic_parser.get_format_instructions() - - prompt = PromptTemplate( - template=dedent(""" - Given: - Context: {context} - Team Objectives: {objectives} - Task Description: {task_description} - - Analyze the above information and provide: - 1. The main objective of the task - 2. A single, primary deliverable - 3. Key features of the deliverable - 4. Important considerations based on team objectives - - Respond in JSON format: - - {format_instructions} - """), - input_variables=["context", "objectives", "task_description"], - partial_variables={"format_instructions": format_instructions}, - ) - - # Chain - prompt_str = prompt.format(**{ - "context": self.context, - "objectives": self.team_goal, - "task_description": task.description - }) - logger.opt(exception=True).debug(f"Prompt: {prompt_str}") - - chain = prompt | self.tool_llm | pydantic_parser - task_deliverable: TaskDeliverableModel = chain.invoke(input={ - "context": self.context, - "objectives": self.team_goal, - "task_description": task.description - }) - if task_deliverable is None: - return TaskDeliverableModel.create_default_task_deliverable(task).to_v2() - return task_deliverable.to_v2() diff --git a/bindings/ceylon/ceylon/__core/llm/llm_task_operator.py b/bindings/ceylon/ceylon/__core/llm/llm_task_operator.py deleted file mode 100644 index bde58dcb..00000000 --- a/bindings/ceylon/ceylon/__core/llm/llm_task_operator.py +++ /dev/null @@ -1,128 +0,0 @@ -import copy -from typing import Dict, List, Set, Any - -from langchain.agents import create_react_agent, AgentExecutor -from langchain_core.messages import SystemMessage, HumanMessage -from langchain_core.output_parsers import StrOutputParser -from langchain_core.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate -from loguru import logger - -from ceylon.task import SubTaskResult -from ceylon.task.task_operation import SubTask -from ceylon.task.task_operator import TaskOperator - - -class LLMTaskOperator(TaskOperator): - """LLM-based task operator.""" - agent_type = "LLM_TASK_OPERATOR" - - def __init__(self, name: str, role: str, context: str, skills: List[str], - tools: List[Any] = None, llm=None, tool_llm=None, verbose=False, - config_file=None, - workspace_id="ceylon_agent_stack", - extra_instructions="", - admin_port=8888, ): - self.context = context - self.extra_instructions = extra_instructions - self.verbose = verbose - self.tools = tools if tools else [] - self.task_history = [] - self.skills = skills - self.llm = copy.copy(llm) - self.tool_llm = copy.copy(tool_llm) - self.history: Dict[str, List[SubTaskResult]] = {} - super().__init__(name=name, role=role, workspace_id=workspace_id, admin_port=admin_port, conf_file=config_file) - - async def get_result(self, task): - return await self.get_llm_response(task) - - async def get_llm_response(self, subtask: SubTask) -> str: - agent_profile = f"You are {self.details().name}, a {self.details().role} {self.context}. Your key skills include: {', '.join(self.skills)}" - - task_info = f""" - Task: {subtask.name} - Description: {subtask.description} - Expected Output: {subtask.expected_output} - - Additional context: - {self._format_task_history(subtask.parent_task_id, subtask.depends_on)} - - Objective: Provide the most successful response for completing {subtask.name}. - """ - - try: - if self.tools: - return await self._execute_react_agent(agent_profile, task_info) - else: - return await self._execute_simple_llm(agent_profile, task_info) - except Exception as e: - logger.error(f"Error in LLM request: {e}") - return f"Error in processing the task: {str(e)}" - - async def _execute_react_agent(self, agent_profile: str, task_info: str) -> str: - system_template = """ - {agent_profile} - Use the following format: - - Question: the input question you must answer - Thought: you should always think about what to do - Action: the action to take, should be one of {tool_names} - Action Input: the input to the action - Observation: the result of the action - ... (this Thought/Action/Action Input/Observation can repeat N times) - Thought: I now know the final answer - - Final Answer: the final answer to the original input question - """ - - human_template = """ - Question: {input} - Tools: {tools} - Extra Instruction: {extra_instructions} - {agent_scratchpad} - Thought: - """ - - chat_prompt = ChatPromptTemplate.from_messages([ - SystemMessagePromptTemplate.from_template(system_template), - HumanMessagePromptTemplate.from_template(human_template) - ]) - - react_agent = create_react_agent(self.llm, self.tools, prompt=chat_prompt) - agent_executor = AgentExecutor(agent=react_agent, tools=self.tools, verbose=self.verbose, - handle_parsing_errors=True) - - response = await agent_executor.ainvoke({ - "agent_profile": agent_profile, - "input": task_info, - "extra_instructions": self.extra_instructions, - "tools": "\n".join(f"{tool.name}: {tool.description}" for tool in self.tools), - "agent_scratchpad": "", - "tool_names": [tool.name for tool in self.tools], - }) - - return response["output"] - - async def _execute_simple_llm(self, agent_profile: str, task_info: str) -> str: - prompt_template = ChatPromptTemplate.from_messages([ - SystemMessage(content=agent_profile), - HumanMessage(content=task_info) - ]) - - runnable = prompt_template | self.llm | StrOutputParser() - return await runnable.ainvoke({}) - - def _format_task_history(self, task_id, depends_on: Set[str]) -> str: - if task_id not in self.history: - return "" - - results = [] - len_history = 0 - for rest_his in self.history[task_id]: - if rest_his.name in depends_on: - results.append(f"{rest_his.name}: {rest_his.result}\n") - len_history += 1 - if len_history == 0: - return "" - logger.info(f"Task history length: {len_history}") - return "\n".join(results) diff --git a/bindings/ceylon/ceylon/__core/llm/tools/__init__.py b/bindings/ceylon/ceylon/__core/llm/tools/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/ceylon/__core/llm/tools/file_publisher_tool.py b/bindings/ceylon/ceylon/__core/llm/tools/file_publisher_tool.py deleted file mode 100644 index 60b511cc..00000000 --- a/bindings/ceylon/ceylon/__core/llm/tools/file_publisher_tool.py +++ /dev/null @@ -1,63 +0,0 @@ -import unittest -from typing import Any, Type, Optional -from unittest.mock import patch, mock_open, Mock - -from langchain_core.callbacks import CallbackManagerForToolRun -from langchain_core.pydantic_v1 import BaseModel, Field -from langchain_core.tools import BaseTool - - -class FilePublisherSchema(BaseModel): - """Input for SendMessageTool.""" - - file_content: str = Field( - ..., - description="The file content to be published. This should be a string containing the text or data that needs to be published.", - ) - file_name: str = Field( - ..., - description="The file name to be created. This should be a string containing the name of the file to be created.", - ) - - -class FilePublisherTool(BaseTool): - name = "File Publisher" - description: str = ( - """ - Use this tool to publish content in a file. use the `file_content` and `file_name` parameters - to define the content and the name of the file to be created. - parameters: - file_content (str): The content to be published. This should be a string containing the text or data that needs to be published. - file_name (str): The name of the file to be created. This should be a string containing the name of the file to be created. - """ - ) - - args_schema: Type[FilePublisherSchema] = FilePublisherSchema - - def _run(self, - file_content: str, - file_name: str, - run_manager: Optional[CallbackManagerForToolRun] = None, ) -> str: - """ - Publishes the given content. - - Parameters: - file_content (str): The content to be published. This should be a string containing the text or data that needs to be published. - file_name (str): The name of the file to be created. This should be a string containing the name of the file to be created. - - Returns: - None - """ - print(f"Publishing content") - name = f"content-{file_name}.txt" - - try: - # Open the file in write mode - with open(name, "a", encoding="utf-8") as f: - f.write(file_content) - return f"Published {file_content} in {name}" - except Exception as e: - return f"An error occurred: {e}" - - async def _arun(self, *args: Any, **kwargs: Any, ) -> Any: - return self._run(*args, **kwargs) diff --git a/bindings/ceylon/ceylon/__core/llm/tools/search_tool.py b/bindings/ceylon/ceylon/__core/llm/tools/search_tool.py deleted file mode 100644 index f868e529..00000000 --- a/bindings/ceylon/ceylon/__core/llm/tools/search_tool.py +++ /dev/null @@ -1,43 +0,0 @@ -import json -import os - -import requests -from langchain_core.tools import tool - - -class SearchTools: - - @tool("Search internet") - def search_internet(query): - """Useful to search the internet about a given topic and return relevant - results.""" - return SearchTools.search(query) - - @tool("Search instagram") - def search_instagram(query): - """Useful to search for instagram post about a given topic and return relevant - results.""" - query = f"site:instagram.com {query}" - return SearchTools.search(query) - - def search(query, n_results=5): - url = "https://google.serper.dev/search" - payload = json.dumps({"q": query}) - headers = { - 'X-API-KEY': os.environ['SERPER_API_KEY'], - 'content-type': 'application/json' - } - response = requests.request("POST", url, headers=headers, data=payload) - results = response.json()['organic'] - stirng = [] - for result in results[:n_results]: - try: - stirng.append('\n'.join([ - f"Title: {result['title']}", f"Link: {result['link']}", - f"Snippet: {result['snippet']}", "\n-----------------" - ])) - except KeyError: - next - - content = '\n'.join(stirng) - return f"\nSearch result: {content}\n" diff --git a/bindings/ceylon/ceylon/__core/task/__init__.py b/bindings/ceylon/ceylon/__core/task/__init__.py deleted file mode 100644 index f4375aad..00000000 --- a/bindings/ceylon/ceylon/__core/task/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .task_operation import SubTask, SubTaskResult, TaskAssignment, Task -from .task_coordinator import TaskCoordinator -from .task_operator import TaskOperator diff --git a/bindings/ceylon/ceylon/__core/task/task_coordinator.py b/bindings/ceylon/ceylon/__core/task/task_coordinator.py deleted file mode 100644 index 7c58c7da..00000000 --- a/bindings/ceylon/ceylon/__core/task/task_coordinator.py +++ /dev/null @@ -1,139 +0,0 @@ -from typing import List, Dict - -from loguru import logger - -from ceylon import CoreAdmin, on_message -from ceylon.ceylon import AgentDetail -from ceylon.static_val import DEFAULT_WORKSPACE_ID, DEFAULT_WORKSPACE_PORT -from ceylon.task import Task, SubTaskResult, TaskAssignment, SubTask -from ceylon.task.task_operation import TaskResultStatus, TaskResult -from ceylon.task.task_operator import TaskOperator - - -class TaskCoordinator(CoreAdmin): - tasks: List[Task] = [] - agents: List[TaskOperator] = [] - results: Dict[str, List[SubTaskResult]] = {} - - def __init__(self, tasks: List[Task] = None, agents: List[TaskOperator] = None, name=DEFAULT_WORKSPACE_ID, - port=DEFAULT_WORKSPACE_PORT, - *args, - **kwargs): - self.tasks = tasks if tasks is not None else [] - self.agents = agents if agents is not None else [] - self.on_init() - super().__init__(name=name, port=port, *args, **kwargs) - - def on_init(self): - pass - - async def update_task(self, idx: int, task: Task) -> Task: - return task - - async def get_task_executor(self, task: SubTask) -> str: - return task.executor - - async def run(self, inputs: bytes): - for idx, task in enumerate(self.tasks): - task = await self.update_task(idx, task) - logger.info(f"Validating task {task.name}") - if task.validate_sub_tasks(): - logger.info(f"Task {task.name} is valid") - else: - logger.info(f"Task {task.name} is invalid") - del self.tasks[idx] - - await self.run_tasks() - - async def run_tasks(self): - if len(self.tasks) == 0: - logger.info("No tasks found") - return - for task in self.tasks: - self.results[task.id] = [] - sub_tasks = task.get_next_subtasks() - if len(sub_tasks) == 0: - logger.info(f"Task {task.name} has no subtasks") - continue - for sub_task in sub_tasks: - if sub_task is None: - continue - subtask_name, subtask_ = sub_task - logger.info(f"Assigning agent to subtask {subtask_name}") - if subtask_.executor is None: - assigned_agent = await self.get_task_executor(subtask_) - subtask_ = task.update_subtask_executor(subtask_name, assigned_agent) - await self.broadcast_data( - TaskAssignment(task=subtask_, assigned_agent=subtask_.executor)) - logger.info(f"Assigned agent {subtask_.executor} to subtask {subtask_name}") - - @on_message(type=SubTaskResult) - async def on_task_result(self, result: SubTaskResult): - logger.info(f"Received task result: {result}") - if result.status == TaskResultStatus.COMPLETED: - for idx, task in enumerate(self.tasks): - sub_tasks = task.get_next_subtasks() - for sub_task in sub_tasks: - print(result.task_id, sub_task[1].id, result.task_id == sub_task[1].id) - if sub_task is None or result.task_id != sub_task[1].id: - continue - if result.task_id == sub_task[1].id: - task.update_subtask_status(sub_task[1].name, result.result) - break - - # Task is completed - for task in self.tasks: - if task.is_completed(): - if task.id == result.task_id: - await self.broadcast_data(TaskResult(task_id=task.id, result=result.result)) - - if self.all_tasks_completed(): - await self.end_task_management() - - await self.run_tasks() - - def all_tasks_completed(self) -> bool: - for task in self.tasks: - subtask_completed_status = [st.completed for st in task.subtasks.values()] - if not all(subtask_completed_status): - return False - return True - - async def end_task_management(self): - logger.info("All tasks completed. Results:") - for task in self.tasks: - logger.info(f"Task {task.id} results:") - for result in self.results[task.id]: - logger.info(f" Subtask {result.subtask_id}: {result.result}") - await self.stop() - - def do(self, inputs: bytes = b'') -> List[Task]: - self.run_admin(inputs, self.agents) - return self.tasks - - async def async_do(self, inputs: bytes = b'') -> List[Task]: - await self.arun_admin(inputs, self.agents) - return self.tasks - - async def on_agent_connected(self, topic: "str", agent: AgentDetail): - logger.info(f"Agent connected: {agent}") - await super().on_agent_connected(topic, agent) - await self.run_tasks() - - async def add_tasks(self, tasks: List[Task]): - self.tasks.extend(tasks) - await self.run_tasks() - - async def add_task(self, task: Task): - self.tasks.extend([task]) - await self.run_tasks() - - def add_agents(self, agents: List[TaskOperator]): - self.agents.extend(agents) - self.on_init() - - @on_message(type=Task) - async def on_add_task(self, task: Task): - logger.info(f"Adding task {task} to coordinator") - task.reinitialize() - await self.add_tasks([task]) diff --git a/bindings/ceylon/ceylon/__core/task/task_human_intractive_operator.py b/bindings/ceylon/ceylon/__core/task/task_human_intractive_operator.py deleted file mode 100644 index 5f2d3dd9..00000000 --- a/bindings/ceylon/ceylon/__core/task/task_human_intractive_operator.py +++ /dev/null @@ -1,18 +0,0 @@ -import abc -from typing import Any - -from ceylon.static_val import DEFAULT_WORKSPACE_ID, DEFAULT_WORKSPACE_PORT -from ceylon.task.task_operator import TaskOperator - - -class TaskOperatorWithHumanInteractive(TaskOperator, abc.ABC): - agent_type = "TASK_OPERATOR_WITH_HUMAN_INTERACTIVE" - - def __init__(self, name: str, role: str = "Get Human Inputs from User", workspace_id: str = DEFAULT_WORKSPACE_ID, - admin_port: int = DEFAULT_WORKSPACE_PORT, *args, **kwargs): - super().__init__(name, role, workspace_id, admin_port, *args, **kwargs) - - async def get_result(self, task) -> Any: - # Get message from user - message = input() - return message diff --git a/bindings/ceylon/ceylon/__core/task/task_operation.py b/bindings/ceylon/ceylon/__core/task/task_operation.py deleted file mode 100644 index 803976f4..00000000 --- a/bindings/ceylon/ceylon/__core/task/task_operation.py +++ /dev/null @@ -1,313 +0,0 @@ -import datetime -import enum -from typing import List, Optional, Tuple, Set, Dict -from uuid import uuid4 - -import networkx as nx -from loguru import logger -from pydantic import BaseModel -from pydantic import Field - - -class SubTask(BaseModel): - id: str = Field(default_factory=lambda: str(uuid4())) - parent_task_id: Optional[str] = Field(default=None) - name: str = Field(description="the name of the subtask write in snake_case") - description: str = Field(description="the description of the subtask, Explains the task in detail") - expected_output: str = Field(description="the expected output of the subtask", default="") - required_specialty: str = Field(description="the required specialty of the subtask", default="") - depends_on: Set[str] = Field(default_factory=set) - completed: bool = False - completed_at: Optional[float] = None - - result: Optional[str] = None - executor: Optional[str] = None - - def complete(self, result: Optional[str] = None): - self.result = result - self.completed_at = datetime.datetime.now().timestamp() - self.completed = True - - def __str__(self): - status = "Completed" if self.completed else "Pending" - return f"SubTask: {self.name} (ID: {self.id}) - {status} - Dependencies: {self.depends_on} - Expected Output: {self.expected_output}" - - def reset(self): - self.result = None - self.completed_at = None - self.completed = False - - -class TaskDeliverable(BaseModel): - objective: str = Field( - description="The main objective of the task", - default="" - ) - deliverable: str = Field( - description="The single, primary deliverable for the task", - default="" - ) - key_features: List[str] = Field( - description="Key features of the deliverable", - default=[] - ) - considerations: List[str] = Field( - description="Important considerations or constraints for the deliverable", - default=[] - ) - - def __str__(self): - return f"TaskDeliverable: {self.deliverable} - Key Features: {self.key_features} - Considerations: {self.considerations} - Objective: {self.objective}" - - @staticmethod - def default(description: str) -> 'TaskDeliverable': - return TaskDeliverable( - objective="Complete the assigned task", - deliverable=description, - key_features=["Basic functionality"], - considerations=["Meet minimum requirements"] - ) - - -class Task(BaseModel): - id: str = Field(default_factory=lambda: str(uuid4())) - name: str - description: str - subtasks: Dict[str, SubTask] = Field(default_factory=dict) - - execution_order: List[str] = Field(default_factory=list) - - metadata: Dict[str, str] = Field(default_factory=dict, alias="metadata", description="metadata") - task_deliverable: TaskDeliverable = Field(default=None) - - max_subtasks: int = Field(default=5, description="max number of subtasks") - - def reinitialize(self): - for subtask in self.subtasks.values(): - subtask.parent_task_id = self.id - subtask.reset() - self._validate_dependencies() - self.execution_order = self.get_execution_order() - - def add_subtask(self, subtask: SubTask): - subtask.parent_task_id = self.id - self.subtasks[subtask.name] = subtask - self._validate_dependencies() - self.execution_order = self.get_execution_order() - - def set_deliverable(self, task_deliverable: TaskDeliverable): - self.task_deliverable = task_deliverable - - def _validate_dependencies(self): - graph = self._create_dependency_graph() - if not nx.is_directed_acyclic_graph(graph): - raise ValueError("The dependencies create a cycle") - - def _create_dependency_graph(self) -> nx.DiGraph: - graph = nx.DiGraph() - for subtask in self.subtasks.values(): - graph.add_node(subtask.name) - for dep in subtask.depends_on: - if dep in self.subtasks: - graph.add_edge(dep, subtask.name) - return graph - - def validate_sub_tasks(self) -> bool: - subtask_names = set(self.subtasks.keys()) - - # Check if all dependencies are present - for subtask in self.subtasks.values(): - if not subtask.depends_on.issubset(subtask_names): - missing_deps = subtask.depends_on - subtask_names - logger.info(f"Subtask '{subtask.name}' has missing dependencies: {missing_deps}") - return False - - # Check for circular dependencies - try: - self._validate_dependencies() - except ValueError as e: - print(f"Circular dependency detected: {str(e)}") - return False - - return True - - def get_execution_order(self) -> List[str]: - graph = self._create_dependency_graph() - return list(nx.topological_sort(graph)) - - # def get_next_subtask(self) -> Optional[Tuple[str, SubTask]]: - # for subtask_name in self.execution_order: - # subtask = self.subtasks[subtask_name] - # if all(self.subtasks[dep].completed for dep in subtask.depends_on): - # return (subtask_name, subtask) - # return None - - def get_next_subtasks(self) -> List[Tuple[str, SubTask]]: - subtasks = [] - for subtask_name in self.execution_order: - subtask = self.subtasks[subtask_name] - if all(self.subtasks[dep].completed for dep in subtask.depends_on): - subtasks.append((subtask_name, subtask)) - return subtasks - - def update_subtask_status(self, subtask_name: str, result: str): - if subtask_name not in self.subtasks: - raise ValueError(f"Subtask {subtask_name} not found") - - subtask = self.subtasks[subtask_name] - if result is not None: - subtask.complete(result) - - if subtask_name in self.execution_order: - self.execution_order.remove(subtask_name) - - def update_subtask_executor(self, subtask_name: str, executor: str) -> SubTask: - if subtask_name not in self.subtasks: - raise ValueError(f"Subtask {subtask_name} not found") - subtask = self.subtasks[subtask_name] - subtask.executor = executor - return subtask - - def get_sub_task_by_name(self, subtask_name: str) -> SubTask: - if subtask_name not in self.subtasks: - raise ValueError(f"Subtask {subtask_name} not found") - - return self.subtasks[subtask_name] - - def is_completed(self) -> bool: - return all(subtask.completed for subtask in self.subtasks.values()) - - @property - def sub_tasks(self) -> List[SubTask]: - tasks = list(self.subtasks.values()) - tasks.sort(key=lambda x: x.completed_at) - return tasks - - @property - def final_answer(self) -> Optional[str]: - if not self.is_completed() or len(self.sub_tasks) == 0: - return None - return self.sub_tasks[-1].result - - def __str__(self): - return f"Task: {self.name}\nSubtasks:\n" + "\n".join(f"\t{st}" for st in self.subtasks.values()) - - @staticmethod - def create_task(name: str, description: str, subtasks: List[SubTask] = None) -> 'Task': - task = Task(name=name, description=description) - if subtasks: - for subtask in subtasks: - task.add_subtask(subtask) - return task - - -class TaskAssignment(BaseModel): - task: SubTask - assigned_agent: str - - -class TaskResultStatus(enum.Enum): - IN_PROGRESS = "IN_PROGRESS" - COMPLETED = "COMPLETED" - FAILED = "FAILED" - - -class SubTaskResult(BaseModel): - task_id: str - parent_task_id: str - agent: str - result: str - name: str - description: str - status: TaskResultStatus - - -class TaskResult(BaseModel): - task_id: str - final_answer: str - - -if __name__ == "__main__": - def execute_task(task: Task) -> None: - execution_step = 0 - while True: - # Get the next subtask - next_subtasks: List[tuple[str, SubTask]] = task.get_next_subtasks() - print(f"Step {execution_step}: {next_subtasks}") - if next_subtasks is None or len(next_subtasks) == 0: - break - for next_subtask in next_subtasks: - # If there are no more subtasks, break the loop - if next_subtask is None: - break - - subtask_name, subtask = next_subtask - print(f"Executing: {subtask}") - - # Here you would actually execute the subtask - # For this example, we'll simulate execution with a simple print statement - print(f"Simulating execution of {subtask_name}") - - # Simulate a result (in a real scenario, this would be the outcome of the subtask execution) - result = "Success" - - # Update the subtask status - task.update_subtask_status(subtask_name, result) - - # Check if the entire task is completed - if task.is_completed(): - print("All subtasks completed successfully!") - break - - # Final check to see if all subtasks were completed - if task.is_completed(): - print("Task execution completed successfully!") - else: - print("Task execution incomplete. Some subtasks may have failed.") - execution_step += 1 - - - # Create a task with initial subtasks - web_app = Task.create_task("Build Web App", "Create a simple web application", - subtasks=[ - SubTask(name="setup", description="Set up the development environment", - required_specialty="Knowledge about deployment and development tools"), - SubTask(name="database", description="Set up the database", - required_specialty="Knowledge about database management tools"), - SubTask(name="testing", description="Perform unit and integration tests", - depends_on={"backend", "frontend"}, - required_specialty="Knowledge about testing tools"), - SubTask(name="frontend", description="Develop the frontend UI", - depends_on={"setup", "database"}, - required_specialty="Knowledge about frontend tools"), - SubTask(name="backend", description="Develop the backend API", - depends_on={"setup", "database"}, - required_specialty="Knowledge about backend tools"), - SubTask(name="deployment", description="Deploy the application", - depends_on={"testing", "qa"}, - required_specialty="Knowledge about deployment tools and CI tools"), - SubTask(name="delivery", description="Deploy the application", - depends_on={"deployment"}, - required_specialty="Knowledge about delivery tools"), - SubTask(name="qa", description="Perform quality assurance", - depends_on={"testing"}, - required_specialty="Knowledge about testing tools") - ]) - - # Execute the task - print("Execution order:", [web_app.subtasks[task_id].name for task_id in web_app.get_execution_order()]) - - if web_app.validate_sub_tasks(): - print("Subtasks are valid") - - print("\nExecuting task:") - execute_task(task=web_app) - - print("\nFinal task status:") - print(web_app) - else: - print("Subtasks are invalid") - - # Serialization example - print("\nSerialized Task:") - print(web_app.model_dump_json(indent=2)) diff --git a/bindings/ceylon/ceylon/__core/task/task_operator.py b/bindings/ceylon/ceylon/__core/task/task_operator.py deleted file mode 100644 index 2f9e9f9d..00000000 --- a/bindings/ceylon/ceylon/__core/task/task_operator.py +++ /dev/null @@ -1,80 +0,0 @@ -import abc -from typing import Dict, List, Any - -from loguru import logger - -from ceylon import Agent, on_message -from ceylon.static_val import DEFAULT_WORKSPACE_ID, DEFAULT_WORKSPACE_PORT, DEFAULT_WORKSPACE_IP, DEFAULT_CONF_FILE -from ceylon.task import TaskAssignment, SubTaskResult -from ceylon.task.task_operation import TaskResultStatus - - -class TaskOperator(Agent, abc.ABC): - agent_type = "TASK_OPERATOR" - - def __init__(self, name: str, role: str, - conf_file=None, - workspace_id: str = DEFAULT_WORKSPACE_ID, - admin_port: int = DEFAULT_WORKSPACE_PORT, - admin_ip: str = DEFAULT_WORKSPACE_IP, - *args, - **kwargs): - self.task_history = [] - self.exeuction_history = [] - self.history: Dict[str, List[SubTaskResult]] = {} - super().__init__(name=name, role=role, workspace_id=workspace_id, admin_port=admin_port, admin_ip=admin_ip, - conf_file=conf_file, - *args, **kwargs) - - @on_message(type=TaskAssignment) - async def on_task_assignment(self, data: TaskAssignment): - if data.assigned_agent == self.details().name and data.task.id not in self.exeuction_history: - self.exeuction_history.append(data.task.id) - status = TaskResultStatus.IN_PROGRESS - result = None - try: - logger.info(f"{self.details().name} received subtask: {data.task.description}") - result = await self.get_result(data.task) - status = TaskResultStatus.COMPLETED - logger.info(f"{self.details().name} completed subtask: {data.task.description}") - except Exception as e: - logger.info(f"{self.details().name} failed subtask: {data.task.description}") - for idx, task in enumerate(self.exeuction_history): - if task == data.task.id: - del self.exeuction_history[idx] - break - logger.exception(e) - result = str(e) - status = TaskResultStatus.FAILED - - result_task = SubTaskResult(task_id=data.task.id, - name=data.task.name, - description=data.task.description, - agent=self.details().name, - parent_task_id=data.task.parent_task_id, - result=result, - status=status) - # Update task history - if status == TaskResultStatus.COMPLETED: - await self.add_result_to_history(result_task) - await self.broadcast_data(result_task) - logger.info(f"{self.details().name} sent subtask result: {data.task.description}") - - @on_message(type=SubTaskResult) - async def on_task_result(self, data: SubTaskResult): - await self.add_result_to_history(data) - - async def add_result_to_history(self, data: SubTaskResult): - if data.parent_task_id in self.history: - # If the task result already exists, replace it - for idx, result in enumerate(self.history[data.parent_task_id]): - if result.task_id == data.task_id: - self.history[data.parent_task_id][idx] = data - return - self.history[data.parent_task_id].append(data) - else: - self.history[data.parent_task_id] = [data] - - @abc.abstractmethod - async def get_result(self, task) -> Any: - pass diff --git a/bindings/ceylon/ceylon/__core/task/test.py b/bindings/ceylon/ceylon/__core/task/test.py deleted file mode 100644 index f2b7be55..00000000 --- a/bindings/ceylon/ceylon/__core/task/test.py +++ /dev/null @@ -1,63 +0,0 @@ -from loguru import logger - -from ceylon.task import Task, SubTask -from task_coordinator import TaskCoordinator -from task_operator import TaskOperator - - -class DeveloperAgent(TaskOperator): - async def get_result(self, task): - # Simulate task execution - logger.info(f"Developer agent executing task: {task.name}") - return f"Completed {task.name}" - - -class QAAgent(TaskOperator): - async def get_result(self, task): - # Simulate task execution - logger.info(f"QA agent executing task: {task.name}") - return f"Tested {task.name}" - - -async def main(): - network_name = "localhost-task-coordinator" - network_port = 8000 - # Create a task with subtasks - web_app = Task.create_task( - "Build Web App", - "Create a simple web application", - subtasks=[ - SubTask(name="setup", description="Set up the development environment", required_specialty="Developer", - executor="Alice"), - SubTask(name="backend", description="Develop the backend API", depends_on={"setup"}, - required_specialty="Developer", - executor="Alice"), - SubTask(name="frontend", description="Develop the frontend UI", depends_on={"setup"}, - required_specialty="Developer", - executor="Alice"), - SubTask(name="testing", description="Perform unit and integration tests", - depends_on={"backend", "frontend"}, required_specialty="QA", - executor="Bob"), - ] - ) - - # Create specialized agents - developer = DeveloperAgent(name="Alice", role="Developer", workspace_id=network_name, admin_port=network_port) - qa_engineer = QAAgent(name="Bob", role="QA", workspace_id=network_name, admin_port=network_port) - - # Create TaskCoordinator - coordinator = TaskCoordinator(tasks=[web_app], agents=[developer, qa_engineer], name=network_name, - port=network_port) - - # Run the task management process - await coordinator.async_do(b"") - - # Print the final task status - print("\nFinal task status:") - print(web_app) - - -if __name__ == "__main__": - import asyncio - - asyncio.run(main()) diff --git a/bindings/ceylon/ceylon/__core/utils/__init__.py b/bindings/ceylon/ceylon/__core/utils/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/ceylon/__core/utils/agent_monitor.py b/bindings/ceylon/ceylon/__core/utils/agent_monitor.py deleted file mode 100644 index ca5667ba..00000000 --- a/bindings/ceylon/ceylon/__core/utils/agent_monitor.py +++ /dev/null @@ -1,28 +0,0 @@ -import pickle - -from loguru import logger - -from ceylon import Agent -from ceylon.static_val import DEFAULT_WORKSPACE_ID, DEFAULT_WORKSPACE_PORT - - -class AgentMonitor(Agent): - - def __init__(self, name="monitor", - workspace_id=DEFAULT_WORKSPACE_ID, - admin_port=DEFAULT_WORKSPACE_PORT, - admin_peer="", - conf_file=None, - role="worker"): - super().__init__( - name=name, - workspace_id=workspace_id, - admin_port=admin_port, - admin_peer=admin_peer, - conf_file=conf_file, - role=role if role else name - ) - - async def on_message(self, agent_id: "str", data: "bytes", time: "int"): - data = pickle.loads(data) - logger.info((agent_id, data, time)) diff --git a/bindings/ceylon/ceylon/agents/__init__.py b/bindings/ceylon/ceylon/agents/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/ceylon/agents/agents.py b/bindings/ceylon/ceylon/agents/agents.py deleted file mode 100644 index b0756ff1..00000000 --- a/bindings/ceylon/ceylon/agents/agents.py +++ /dev/null @@ -1,116 +0,0 @@ -# agents.py -import asyncio -import json -from typing import List, Dict - -import ceylon -from ceylon.base.agents import BaseMessageHandler, BaseProcessor, BaseEventHandler -from ceylon.ceylon.ceylon import uniffi_set_event_loop - - -class ChatMessageHandler(BaseMessageHandler): - def __init__(self): - self.messages: List[Dict] = [] - - async def process_message(self, agent_id: str, message: dict, timestamp: int): - formatted_msg = { - "from": agent_id, - "content": message, - "time": timestamp, - } - self.messages.append(formatted_msg) - print(f"Message from {agent_id}: {message}") - - -class ChatProcessor(BaseProcessor): - async def process_data(self, input_data: dict): - print(f"Processing input data: {input_data}") - # Add your processing logic here - await asyncio.sleep(0.1) # Simulate some processing - - -class ChatEventHandler(BaseEventHandler): - def __init__(self): - self.connected_agents: Dict[str, ceylon.AgentDetail] = {} - - async def handle_agent_connected(self, topic: str, agent: ceylon.AgentDetail): - self.connected_agents[agent.id] = agent - print(f"Agent {agent.name} ({agent.id}) connected to topic {topic}") - - async def handle_agent_disconnected(self, topic: str, agent: ceylon.AgentDetail): - if agent.id in self.connected_agents: - del self.connected_agents[agent.id] - print(f"Agent {agent.name} ({agent.id}) disconnected from topic {topic}") - - -class ChatAdminAgent: - def __init__(self, name: str, port: int): - self.config = ceylon.AdminAgentConfig(name=name, port=port) - self.message_handler = ChatMessageHandler() - self.processor = ChatProcessor() - self.event_handler = ChatEventHandler() - self.agent = ceylon.AdminAgent( - self.config, - self.message_handler, - self.processor, - self.event_handler - ) - - async def start(self, initial_data: dict, workers: List['ChatWorkerAgent']): - uniffi_set_event_loop(asyncio.get_event_loop()) - try: - worker_agents = [w.agent for w in workers] - await self.agent.start(json.dumps(initial_data).encode('utf-8'), worker_agents) - except Exception as e: - print(f"Error starting admin agent: {e}") - - async def stop(self): - await self.agent.stop() - - async def broadcast(self, message: dict): - await self.agent.broadcast(json.dumps(message).encode('utf-8')) - - async def send_direct(self, peer_id: str, message: dict): - await self.agent.send_direct(peer_id, json.dumps(message).encode('utf-8')) - - def get_connected_peers(self) -> List[ceylon.AgentDetail]: - # TODO - return self.agent.get_connected_peers() - - -class ChatWorkerAgent: - def __init__(self, name: str, workspace_id: str, admin_peer: str, role: str, admin_port: int, admin_ip: str): - self.config = ceylon.WorkerAgentConfig( - name=name, - work_space_id=workspace_id, - admin_peer=admin_peer, - role=role, - admin_port=admin_port, - admin_ip=admin_ip, - conf_file=".ceylon_network" - ) - self.message_handler = ChatMessageHandler() - self.processor = ChatProcessor() - self.event_handler = ChatEventHandler() - self.agent = ceylon.WorkerAgent( - self.config, - self.message_handler, - self.processor, - self.event_handler - ) - - async def start(self, initial_data: dict): - uniffi_set_event_loop(asyncio.get_event_loop()) - try: - await self.agent.start(json.dumps(initial_data).encode('utf-8')) - except Exception as e: - print(f"Error starting worker agent: {e}") - - async def stop(self): - await self.agent.stop() - - async def broadcast(self, message: dict): - await self.agent.broadcast(json.dumps(message).encode('utf-8')) - - async def send_direct(self, peer_id: str, message: dict): - await self.agent.send_direct(peer_id, json.dumps(message).encode('utf-8')) diff --git a/bindings/ceylon/tests/ceylon_agent_test.py b/bindings/ceylon/tests/ceylon_agent_test.py deleted file mode 100644 index 9b5580c6..00000000 --- a/bindings/ceylon/tests/ceylon_agent_test.py +++ /dev/null @@ -1,61 +0,0 @@ -import asyncio -import pickle -import random - -from ceylon.ceylon import AgentCore, MessageHandler, Processor, AgentDefinition -from ceylon.runner import AgentRunner - - -class Agent(AgentCore, MessageHandler, Processor): - def __init__(self, name, position, instructions, responsibilities): - - super().__init__(definition=AgentDefinition( - id=None, - name=name, - position=position, - instructions=instructions, - responsibilities=responsibilities - ), on_message=self, processor=self) - - async def on_message(self, agent_id, data, time): - definition = await self.definition() - dt = pickle.loads(data) - print(definition.id, agent_id, dt, time) - - ## Write to txt file - # with open(f"test_{name}.txt", "a") as f: - # f.write(dt.decode("utf-8") + "\n") - - async def run(self, inputs): - definition = await self.definition() - while True: - await self.broadcast(pickle.dumps({ - "title": "How to use AI for Machine Learning", - "sender": definition.name - })) - await asyncio.sleep(random.randint(1, 10)) - - -# -async def main(): - runner = AgentRunner(workspace_name="ceylon-ai") - runner.register_agent(Agent(name="ceylon-ai-1", - responsibilities=["writer", "researcher"], - instructions=["How to use AI for Machine Learning"], - position="leader")) - runner.register_agent(Agent(name="ceylon-ai-2", responsibilities=["writer", "researcher"], - instructions=["How to use AI for Machine Learning"], position="leader")) - runner.register_agent(Agent(name="ceylon-ai-3", responsibilities=["writer", "researcher"], - instructions=["How to use AI for Machine Learning"], position="leader")) - - for i in range(4, 5): - runner.register_agent(Agent(name=f"ceylon-ai-{i}", responsibilities=["writer", "researcher"], - instructions=["How to use AI for Machine Learning"], position="leader")) - - await runner.run({ - "title": "How to use AI for Machine Learning", - }) - - -if __name__ == '__main__': - asyncio.run(main()) diff --git a/bindings/ceylon/tests/example_project/__init__.py b/bindings/ceylon/tests/example_project/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/tests/example_project/chat_gpt_task_manager.py b/bindings/ceylon/tests/example_project/chat_gpt_task_manager.py deleted file mode 100644 index 21930271..00000000 --- a/bindings/ceylon/tests/example_project/chat_gpt_task_manager.py +++ /dev/null @@ -1,113 +0,0 @@ -import datetime - - -class Task: - def __init__(self, name, priority, due_date=None): - self.name = name - self.priority = priority - self.due_date = due_date - self.completed = False - - def __str__(self): - status = "✓" if self.completed else "✗" - due_date_str = self.due_date.strftime("%Y-%m-%d") if self.due_date else "No due date" - return f"{status} | {self.name} | Priority: {self.priority} | Due: {due_date_str}" - - -class TaskManager: - def __init__(self): - self.tasks = [] - - def add_task(self, name, priority, due_date=None): - task = Task(name, priority, due_date) - self.tasks.append(task) - print(f"Task '{name}' added.") - - def list_tasks(self, show_completed=False): - print("\n--- Task List ---") - for i, task in enumerate(self.tasks): - if show_completed or not task.completed: - print(f"{i + 1}. {task}") - print("-----------------\n") - - def complete_task(self, task_index): - try: - task = self.tasks[task_index - 1] - task.completed = True - print(f"Task '{task.name}' marked as completed.") - except IndexError: - print("Invalid task number.") - - def list_tasks_by_date(self, date): - print(f"\n--- Tasks Due on {date.strftime('%Y-%m-%d')} ---") - for i, task in enumerate(self.tasks): - if task.due_date == date and not task.completed: - print(f"{i + 1}. {task}") - print("-----------------\n") - - def download_task_list(self, filename="tasks.txt"): - with open(filename, "w") as f: - for task in self.tasks: - f.write(str(task) + "\n") - print(f"Task list saved to {filename}.") - - def check_finished_tasks(self): - print("\n--- Completed Tasks ---") - for i, task in enumerate(self.tasks): - if task.completed: - print(f"{i + 1}. {task}") - print("----------------------\n") - - -def main(): - manager = TaskManager() - - while True: - print("\nTask Manager Options:") - print("1. Add a Task") - print("2. List Tasks") - print("3. Mark Task as Completed") - print("4. List Tasks by Due Date") - print("5. Download Task List") - print("6. Check Finished Tasks") - print("7. Exit") - - choice = input("Choose an option: ") - - if choice == "1": - name = input("Enter task name: ") - priority = input("Enter task priority (1-5): ") - due_date_input = input("Enter due date (YYYY-MM-DD) or leave empty: ") - due_date = datetime.datetime.strptime(due_date_input, "%Y-%m-%d").date() if due_date_input else None - manager.add_task(name, priority, due_date) - - elif choice == "2": - show_completed = input("Show completed tasks? (yes/no): ").strip().lower() == 'yes' - manager.list_tasks(show_completed) - - elif choice == "3": - task_index = int(input("Enter task number to mark as completed: ")) - manager.complete_task(task_index) - - elif choice == "4": - date_input = input("Enter date (YYYY-MM-DD): ") - date = datetime.datetime.strptime(date_input, "%Y-%m-%d").date() - manager.list_tasks_by_date(date) - - elif choice == "5": - filename = input("Enter filename to save task list (default: tasks.txt): ") or "tasks.txt" - manager.download_task_list(filename) - - elif choice == "6": - manager.check_finished_tasks() - - elif choice == "7": - print("Exiting Task Manager. Goodbye!") - break - - else: - print("Invalid option. Please choose again.") - - -if __name__ == "__main__": - main() diff --git a/bindings/ceylon/tests/example_project/task_manager_ceylon_result.py b/bindings/ceylon/tests/example_project/task_manager_ceylon_result.py deleted file mode 100644 index 72dd5815..00000000 --- a/bindings/ceylon/tests/example_project/task_manager_ceylon_result.py +++ /dev/null @@ -1,112 +0,0 @@ -import tkinter as tk -from tkinter import messagebox, simpledialog -from tkinter import ttk -import csv -from datetime import datetime - - -class Task: - def __init__(self, title, description, due_date, priority): - self.title = title - self.description = description - self.due_date = due_date - self.priority = priority # Priority can be 'Low', 'Medium', or 'High' - self.completed = False - - def complete(self): - self.completed = True - - def __str__(self): - status = "✓" if self.completed else "✗" - return f"{status} {self.title} (Due: {self.due_date}, Priority: {self.priority})" - - -class TaskManager: - def __init__(self): - self.tasks = [] - - def add_task(self, title, description, due_date, priority): - task = Task(title, description, due_date, priority) - self.tasks.append(task) - - def complete_task(self, index): - if 0 <= index < len(self.tasks): - self.tasks[index].complete() - - def filter_tasks_by_date(self, date_str): - return [task for task in self.tasks if task.due_date == date_str] - - def download_tasks_as_csv(self, filtered_tasks, date_str): - filename = f'tasks_{date_str}.csv' - with open(filename, mode='w', newline='') as file: - writer = csv.DictWriter(file, fieldnames=filtered_tasks[0].__dict__.keys()) - writer.writeheader() - writer.writerows([task.__dict__ for task in filtered_tasks]) - return filename - - -class TaskMasterApp: - def __init__(self, master): - self.master = master - self.master.title("TaskMaster") - self.task_manager = TaskManager() - - self.task_listbox = tk.Listbox(master, selectmode=tk.SINGLE) - self.task_listbox.pack(expand=True, fill=tk.BOTH) - - self.add_button = tk.Button(master, text="Add Task", command=self.add_task) - self.add_button.pack(side=tk.LEFT) - - self.complete_button = tk.Button(master, text="Complete Task", command=self.complete_task) - self.complete_button.pack(side=tk.LEFT) - - self.download_button = tk.Button(master, text="Download Completed Tasks", command=self.download_completed_tasks) - self.download_button.pack(side=tk.LEFT) - - self.check_finished_button = tk.Button(master, text="Check Finished Tasks", command=self.check_finished_tasks) - self.check_finished_button.pack(side=tk.LEFT) - - def add_task(self): - title = simpledialog.askstring("Task Title", "Enter the task title:") - description = simpledialog.askstring("Task Description", "Enter the task description:") - due_date = simpledialog.askstring("Due Date", "Enter the due date (YYYY-MM-DD):") - priority = simpledialog.askstring("Priority", "Enter the priority (Low, Medium, High):") - self.task_manager.add_task(title, description, due_date, priority) - self.update_task_list() - - def complete_task(self): - try: - selected_index = self.task_listbox.curselection()[0] - self.task_manager.complete_task(selected_index) - self.update_task_list() - except IndexError: - messagebox.showwarning("Warning", "No task selected.") - - def download_completed_tasks(self): - date_input = simpledialog.askstring("Download Tasks", - "Enter the date to download completed tasks (YYYY-MM-DD):") - filtered_tasks = self.task_manager.filter_tasks_by_date(date_input) - if filtered_tasks: - filename = self.task_manager.download_tasks_as_csv(filtered_tasks, date_input) - messagebox.showinfo("Download Complete", f"Tasks downloaded as {filename}.") - else: - messagebox.showinfo("No Tasks", "No tasks found for the selected date.") - - def check_finished_tasks(self): - completed_tasks = [task for task in self.task_manager.tasks if task.completed] - if completed_tasks: - completed_tasks_str = "\n".join(str(task) for task in completed_tasks) - messagebox.showinfo("Completed Tasks", f"The following tasks are completed:\n\n{completed_tasks_str}") - else: - messagebox.showinfo("Completed Tasks", "No tasks are completed.") - - def update_task_list(self): - self.task_listbox.delete(0, tk.END) - for task in self.task_manager.tasks: - self.task_listbox.insert(tk.END, str(task)) - - -if __name__ == "__main__": - root = tk.Tk() - app = TaskMasterApp(root) - root.mainloop() diff --git a/bindings/ceylon/tests/example_project/tasks_2024-12-12.csv b/bindings/ceylon/tests/example_project/tasks_2024-12-12.csv deleted file mode 100644 index 3fe13068..00000000 --- a/bindings/ceylon/tests/example_project/tasks_2024-12-12.csv +++ /dev/null @@ -1,2 +0,0 @@ -title,description,due_date,priority,completed -test ,,2024-12-12,Low,True diff --git a/bindings/ceylon/tests/example_project/tasks_2024-12-15.csv b/bindings/ceylon/tests/example_project/tasks_2024-12-15.csv deleted file mode 100644 index c571fb03..00000000 --- a/bindings/ceylon/tests/example_project/tasks_2024-12-15.csv +++ /dev/null @@ -1,2 +0,0 @@ -title,description,due_date,priority,completed -Sample 1,desc,2024-12-15,,False diff --git a/bindings/ceylon/tests/llm_agen_test.py b/bindings/ceylon/tests/llm_agen_test.py deleted file mode 100644 index 22d13525..00000000 --- a/bindings/ceylon/tests/llm_agen_test.py +++ /dev/null @@ -1,108 +0,0 @@ -import asyncio - -from duckduckgo_search import DDGS -from langchain_community.chat_models import ChatOllama, ChatOpenAI -from langchain_core.tools import StructuredTool - -from ceylon import AgentRunner -from ceylon.llm.llm_agent import LLMAgent -from ceylon.tools.file_publisher_tool import FilePublisherTool -from ceylon.tools.search_tool import SearchTool - - -async def main(): - runner = AgentRunner(workspace_name="ceylon-ai") - llm_lib = ChatOllama(model="llama3:instruct") - # llm_lib = ChatOpenAI(model="gpt-4o") - runner.register_agent(LLMAgent( - name="writer", - position="Assistant Writer", - llm=llm_lib, - responsibilities=["Create high-quality, original content that matches the audience's tone and style."], - instructions=[ - "Ensure clarity, accuracy, and proper formatting while respecting ethical guidelines and privacy."] - )) - runner.register_agent(LLMAgent( - name="name_chooser", - position="Select File name", - llm=llm_lib, - responsibilities=["Create high-quality, SEO friendly file name."], - instructions=[ - "Easy to read and understand." - ] - )) - - runner.register_agent(LLMAgent( - name="researcher", - position="Content Researcher", - llm=llm_lib, - responsibilities=[ - "Conducting thorough and accurate research to support content creation.", - "summarize with source references" - - ], - instructions=[ - "Must only Find the most relevant 2 or 3 sources." - "Find credible sources, verify information, and provide comprehensive and relevant " - "data while ensuring ethical " - "standards and privacy are maintained.", - "Must summarize output with source references." - ], - tools=[ - SearchTool() - ] - )) - # - runner.register_agent(LLMAgent( - name="editor", - position="Content Editor", - llm=llm_lib, - responsibilities=[ - "Review and refine content to ensure it meets quality standards and aligns with the editorial guidelines.", - "Write content in a clear and concise manner.", - "Ensure the content is appropriate for the target audience.", - "Ensure the content is engaging and maintains the intended tone and style.", - "Include source references when appropriate." - ], - instructions=[ - "Check for grammatical errors, clarity, and coherence.", - "Ensure the content is engaging and maintains the intended tone and style.", - "Provide constructive feedback to the writer." - ] - )) - # - runner.register_agent(LLMAgent( - name="publisher", - position="Content Publisher", - llm=llm_lib, - responsibilities=[ - "Publish the finalized content using the publishing tools and platforms specified by the writer.", - ], - instructions=[ - "Publish it as finalized and polished content", - ], - tools=[ - FilePublisherTool() - ] - )) - - await runner.run( - { - "request": "I want to create a blog post", - "title": "How to use AI for Machine Learning", - "tone": "informal", - "length": "large", - "style": "creative" - }, - network={ - "name_chooser": [], - "researcher": [], - "writer": ["researcher"], - "editor": ["writer"], - "publisher": ["editor", "name_chooser"] - } - ) - - -if __name__ == '__main__': - asyncio.run(main()) diff --git a/bindings/ceylon/tests/llm_agents/__init__.py b/bindings/ceylon/tests/llm_agents/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/tests/llm_agents/task_manager-ollama-sub-task-automated.py b/bindings/ceylon/tests/llm_agents/task_manager-ollama-sub-task-automated.py deleted file mode 100644 index 6458af0e..00000000 --- a/bindings/ceylon/tests/llm_agents/task_manager-ollama-sub-task-automated.py +++ /dev/null @@ -1,228 +0,0 @@ -import asyncio -from typing import List, Dict - -from langchain.chains import LLMChain -from langchain.prompts import ChatPromptTemplate -from langchain_community.chat_models import ChatOllama -from langchain_core.prompts import PromptTemplate -from langchain_experimental.llms.ollama_functions import OllamaFunctions -from loguru import logger -from pydantic.v1 import BaseModel, Field - -from ceylon import Agent, CoreAdmin, on_message - - -class SubTask(BaseModel): - id: int = Field(description="the id of the subtask") - description: str = Field(description="the description of the subtask, Explains the task in detail") - required_specialty: str = Field(description="the required specialty of the subtask") - - -class SubTaskList(BaseModel): - subtasks: List[SubTask] - - -class Task(BaseModel): - """ - id: int - description: str - subtasks: List[SubTask] - """ - id: int = Field(description="the id of the task") - description: str = Field(description="the description of the task") - subtasks: List[SubTask] = Field(description="the subtasks of the task", default=[]) - - -class TaskAssignment(BaseModel): - task: Task = Field(description="the task assigned to the agent") - subtask: SubTask = Field(description="the subtask assigned to the agent") - assigned_agent: str = Field(description="the agent assigned to the subtask") - - -class TaskResult(BaseModel): - task_id: int = Field(description="the id of the task") - subtask_id: int = Field(description="the id of the subtask") - agent: str = Field(description="the agent who completed the subtask") - result: str = Field(description="the result of the subtask") - - -class SpecializedAgent(Agent): - def __init__(self, name: str, specialty: str): - self.specialty = specialty - super().__init__(name=name, workspace_id="openai_task_management", admin_peer="TaskManager", admin_port=8000) - - @on_message(type=TaskAssignment) - async def on_task_assignment(self, data: TaskAssignment): - if data.assigned_agent == self.details().name: - logger.info(f"{self.details().name} received subtask: {data.subtask.description}") - # Simulate task execution - await asyncio.sleep(2) - result = f"{self.details().name} completed the subtask: {data.subtask.description}" - await self.broadcast_data( - TaskResult(task_id=data.task.id, subtask_id=data.subtask.id, agent=self.details().name, result=result)) - - @on_message(type=TaskResult) - async def other_agents_results(self, result: TaskResult): - logger.info( - f"Received result for subtask {result.subtask_id} of task {result.task_id} from {result.agent}: {result.result}") - - -class TaskManager(CoreAdmin): - tasks: List[Task] = [] - agents: List[SpecializedAgent] = [] - results: Dict[int, List[TaskResult]] = {} - - def __init__(self, tasks: List[Task], agents: List[SpecializedAgent]): - self.tasks = tasks - self.agents = agents - super().__init__(name="openai_task_management", port=8000) - - async def run(self, inputs: bytes): - - for idx, task in enumerate(self.tasks): - if len(task.subtasks) == 0: - generated_tasks = await self.generate_tasks_from_description(task.description) - self.tasks[idx].subtasks = generated_tasks - await self.assign_tasks() - - async def assign_tasks(self): - for task in self.tasks: - self.results[task.id] = [] - for subtask in task.subtasks: - assigned_agent = await self.get_best_agent_for_subtask(subtask) - print(f"Assigned subtask {subtask.id} of task {task.id} to agent {assigned_agent}") - await self.broadcast_data(TaskAssignment(task=task, subtask=subtask, assigned_agent=assigned_agent)) - - @on_message(type=TaskResult) - async def on_task_result(self, result: TaskResult): - self.results[result.task_id].append(result) - logger.info( - f"Received result for subtask {result.subtask_id} of task {result.task_id} from {result.agent}: {result.result}") - if self.all_tasks_completed(): - await self.end_task_management() - - def all_tasks_completed(self) -> bool: - for task in self.tasks: - if len(self.results[task.id]) != len(task.subtasks): - return False - return True - - async def end_task_management(self): - logger.info("All tasks completed. Results:") - for task in self.tasks: - logger.info(f"Task {task.id} results:") - for result in self.results[task.id]: - logger.info(f" Subtask {result.subtask_id}: {result.result}") - await self.stop() - - async def get_best_agent_for_subtask(self, subtask: SubTask) -> str: - agent_specialties = "\n".join([f"{agent.details().name}: {agent.specialty}" for agent in self.agents]) - - llm = ChatOllama(model="llama3.1:latest", temperature=0) - - prompt_template = ChatPromptTemplate.from_template( - """Given the following subtask and list of agents with their specialties, determine which agent is - best suited for the subtask. - - Subtask: {subtask_description} - Required Specialty: {required_specialty} - - Agents and their specialties: - {agent_specialties} - - Respond with only the name of the best-suited agent.""" - ) - - chain = LLMChain(llm=llm, prompt=prompt_template) - response = chain.run(subtask_description=subtask.description, required_specialty=subtask.required_specialty, - agent_specialties=agent_specialties) - return response.strip() - - async def generate_tasks_from_description(self, description: str) -> List[SubTask]: - - # Prompt template - prompt = PromptTemplate.from_template( - """ - Given the following job description, break it down into a main task and 3-5 key subtasks. Each subtask should have a specific description and required specialty. - - Job Description: {description} - - Respond with the tasks and their subtasks in the following format: - - Main Task: - - Subtasks: - 1. - Specialty: - 2. - Specialty: - 3. - Specialty: - (Add up to 2 more subtasks if necessary) - - Additional Considerations: - - Prioritize the subtasks in order of importance or chronological sequence - - Ensure each subtask is distinct and contributes uniquely to the main task - - Use clear, action-oriented language for each description - - If applicable, include any interdependencies between subtasks - """ - ) - - # Chain - llm = OllamaFunctions(model="llama3.1:latest", format="json", temperature=0.7) - structured_llm = llm.with_structured_output(SubTaskList) - chain = prompt | structured_llm - sub_task_list = chain.invoke(input={ - "description": description - }) - return sub_task_list.subtasks - - @staticmethod - def parse_llm_response(response: str) -> List[Task]: - lines = response.splitlines() - tasks = [] - current_task = None - subtasks = [] - for line in lines: - if line.startswith("Task Description:"): - if current_task: - tasks.append(Task(id=len(tasks) + 1, description=current_task, subtasks=subtasks)) - subtasks = [] - current_task = line.replace("Task Description:", "").strip() - elif line.startswith("1.") or line.startswith("2.") or line.startswith("3."): - parts = line.split(" - Specialty: ") - subtask_description = parts[0].split(". ", 1)[1].strip() - required_specialty = parts[1].strip() if len(parts) > 1 else "General" - subtasks.append(SubTask(id=len(subtasks) + 1, description=subtask_description, - required_specialty=required_specialty)) - - if current_task: - tasks.append(Task(id=len(tasks) + 1, description=current_task, subtasks=subtasks)) - - return tasks - - -if __name__ == "__main__": - # Create tasks with subtasks - tasks = [ - Task(id=1, description="Create an article about AI advancements"), - Task(id=2, description="Create a landing page for a new Food product and deploy it on the web"), - Task(id=3, description="Create a data collection form for a new product and deploy it on the web"), - ] - - # Create specialized agents - agents = [ - SpecializedAgent("ContentWriter", "Content writing and research"), - SpecializedAgent("ImageGenerator", "AI image generation and editing"), - SpecializedAgent("Editor", "Proofreading, editing, and formatting"), - SpecializedAgent("SEOMaster", "Search engine optimization and content optimization"), - SpecializedAgent("ContentResearcher", "Content research and analysis"), - SpecializedAgent("UIDesigner", "UI/UX design and frontend development"), - SpecializedAgent("BackendDev", "Backend development and database management"), - SpecializedAgent("FrontendDev", "Frontend development and UI/UX design"), - SpecializedAgent("DevOps", "DevOps and infrastructure management"), - SpecializedAgent("DataAnalyst", "Data analysis and statistics"), - SpecializedAgent("DataScientist", "Data science and machine learning"), - SpecializedAgent("QATester", "Software testing and quality assurance") - ] - - # Create and run task manager - task_manager = TaskManager(tasks, agents) - task_manager.run_admin(inputs=b"", workers=agents) diff --git a/bindings/ceylon/tests/llm_agents/task_manager-ollama-sub-task.py b/bindings/ceylon/tests/llm_agents/task_manager-ollama-sub-task.py deleted file mode 100644 index f6a6c8b2..00000000 --- a/bindings/ceylon/tests/llm_agents/task_manager-ollama-sub-task.py +++ /dev/null @@ -1,152 +0,0 @@ -import asyncio -from dataclasses import dataclass -from typing import List, Dict - -from langchain.chains import LLMChain -from langchain.chat_models import ChatOllama -from langchain.prompts import ChatPromptTemplate -from loguru import logger - -from ceylon import Agent, CoreAdmin, on_message - - -@dataclass -class SubTask: - id: int - description: str - required_specialty: str - - -@dataclass -class Task: - id: int - description: str - subtasks: List[SubTask] - - -@dataclass -class TaskAssignment: - task: Task - subtask: SubTask - assigned_agent: str - - -@dataclass -class TaskResult: - task_id: int - subtask_id: int - agent: str - result: str - - -class SpecializedAgent(Agent): - def __init__(self, name: str, specialty: str): - self.specialty = specialty - super().__init__(name=name, workspace_id="openai_task_management", admin_peer="TaskManager", admin_port=8000) - - @on_message(type=TaskAssignment) - async def on_task_assignment(self, data: TaskAssignment): - if data.assigned_agent == self.details().name: - logger.info(f"{self.details().name} received subtask: {data.subtask.description}") - # Simulate task execution - await asyncio.sleep(2) - result = f"{self.details().name} completed the subtask: {data.subtask.description}" - await self.broadcast_data( - TaskResult(task_id=data.task.id, subtask_id=data.subtask.id, agent=self.details().name, result=result)) - - -class TaskManager(CoreAdmin): - tasks: List[Task] = [] - agents: List[SpecializedAgent] = [] - results: Dict[int, List[TaskResult]] = {} - - def __init__(self, tasks: List[Task], agents: List[SpecializedAgent]): - self.tasks = tasks - self.agents = agents - super().__init__(name="openai_task_management", port=8000) - - async def run(self, inputs: bytes): - await self.assign_tasks() - - async def assign_tasks(self): - for task in self.tasks: - self.results[task.id] = [] - for subtask in task.subtasks: - assigned_agent = await self.get_best_agent_for_subtask(subtask) - print(f"Assigned subtask {subtask.id} of task {task.id} to agent {assigned_agent}") - await self.broadcast_data(TaskAssignment(task=task, subtask=subtask, assigned_agent=assigned_agent)) - - async def get_best_agent_for_subtask(self, subtask: SubTask) -> str: - agent_specialties = "\n".join([f"{agent.details().name}: {agent.specialty}" for agent in self.agents]) - llm = ChatOllama(model="llama3.1:latest", temperature=0) - - prompt_template = ChatPromptTemplate.from_template( - """Given the following subtask and list of agents with their specialties, determine which agent is - best suited for the subtask. - - Subtask: {subtask_description} - Required Specialty: {required_specialty} - - Agents and their specialties: - {agent_specialties} - - Respond with only the name of the best-suited agent.""" - ) - - chain = LLMChain(llm=llm, prompt=prompt_template) - response = chain.run(subtask_description=subtask.description, required_specialty=subtask.required_specialty, - agent_specialties=agent_specialties) - return response.strip() - - @on_message(type=TaskResult) - async def on_task_result(self, result: TaskResult): - self.results[result.task_id].append(result) - logger.info( - f"Received result for subtask {result.subtask_id} of task {result.task_id} from {result.agent}: {result.result}") - if self.all_tasks_completed(): - await self.end_task_management() - - def all_tasks_completed(self) -> bool: - for task in self.tasks: - if len(self.results[task.id]) != len(task.subtasks): - return False - return True - - async def end_task_management(self): - logger.info("All tasks completed. Results:") - for task in self.tasks: - logger.info(f"Task {task.id} results:") - for result in self.results[task.id]: - logger.info(f" Subtask {result.subtask_id}: {result.result}") - await self.stop() - - -if __name__ == "__main__": - # Create tasks with subtasks - tasks = [ - Task(id=1, description="Create an article about AI advancements", subtasks=[ - SubTask(id=1, description="Write the main content of the article", required_specialty="Content writing"), - SubTask(id=2, description="Generate an AI-related image for the article", - required_specialty="Image generation"), - SubTask(id=3, description="Proofread and format the article", required_specialty="Editing and formatting") - ]), - Task(id=2, description="Develop a simple web application", subtasks=[ - SubTask(id=1, description="Design the user interface", required_specialty="UI/UX design"), - SubTask(id=2, description="Implement the backend logic", required_specialty="Backend development"), - SubTask(id=3, description="Test the application", required_specialty="Software testing") - ]) - ] - - # Create specialized agents - agents = [ - SpecializedAgent("ContentWriter", "Content writing and research"), - SpecializedAgent("ImageGenerator", "AI image generation and editing"), - SpecializedAgent("Editor", "Proofreading, editing, and formatting"), - SpecializedAgent("UIDesigner", "UI/UX design and frontend development"), - SpecializedAgent("BackendDev", "Backend development and database management"), - SpecializedAgent("QATester", "Software testing and quality assurance") - ] - - # Create and run task manager - task_manager = TaskManager(tasks, agents) - task_manager.run_admin(inputs=b"", workers=agents) diff --git a/bindings/ceylon/tests/llm_agents/task_manager-ollama-task-automation-with-dependencies.py b/bindings/ceylon/tests/llm_agents/task_manager-ollama-task-automation-with-dependencies.py deleted file mode 100644 index 4c2fdc9d..00000000 --- a/bindings/ceylon/tests/llm_agents/task_manager-ollama-task-automation-with-dependencies.py +++ /dev/null @@ -1,117 +0,0 @@ -from langchain_community.chat_models import ChatOllama - -from ceylon.llm import LLMTaskManager -from ceylon.llm.llm_task_operator import LLMTaskAgent -from ceylon.llm.data_types import Task - -if __name__ == "__main__": - - llm = ChatOllama(model="llama3.1:latest", temperature=0) - # Create tasks with subtasks - tasks = [ - Task(id=1, description="Create an article about AI advancements"), - ] - - # Create specialized agents - specialized_agents = [ - LLMTaskAgent( - name="ContentWriter", - context="Content writing and research", - skills=["Blog writing", "Article writing", "Copywriting", "SEO writing"], - experience_level="Expert", - tools=["Google Docs", "Grammarly", "Hemingway Editor", "WordPress"], - llm=llm - ), - LLMTaskAgent( - name="ImageGenerator", - context="AI image generation and editing", - skills=["DALL-E prompting", "Midjourney", "Photoshop", "Canva"], - experience_level="Advanced", - tools=["DALL-E", "Midjourney", "Adobe Photoshop", "Canva"], - llm=llm - ), - LLMTaskAgent( - name="Editor", - context="Proofreading, editing, and formatting", - skills=["Copy editing", "Content editing", "Style guide implementation", "Formatting"], - experience_level="Expert", - tools=["Microsoft Word", "Google Docs", "Grammarly", "Chicago Manual of Style"], - llm=llm - ), - LLMTaskAgent( - name="SEOMaster", - context="Search engine optimization and content optimization", - skills=["Keyword research", "On-page SEO", "Technical SEO", "Link building"], - experience_level="Expert", - tools=["SEMrush", "Ahrefs", "Google Analytics", "Google Search Console"], - llm=llm - ), - LLMTaskAgent( - name="ContentResearcher", - context="Content research and analysis", - skills=["Academic research", "Market research", "Data collection", "Trend analysis"], - experience_level="Advanced", - tools=["Google Scholar", "JSTOR", "LexisNexis", "Statista"], - llm=llm - ), - LLMTaskAgent( - name="UIDesigner", - context="UI/UX design and frontend development", - skills=["Wireframing", "Prototyping", "User testing", "Responsive design"], - experience_level="Expert", - tools=["Figma", "Sketch", "Adobe XD", "InVision"], - llm=llm - ), - LLMTaskAgent( - name="BackendDev", - context="Backend development and database management", - skills=["Python", "Node.js", "SQL", "RESTful API design"], - experience_level="Expert", - tools=["Django", "Express.js", "PostgreSQL", "Docker"], - llm=llm - ), - LLMTaskAgent( - name="FrontendDev", - context="Frontend development and UI/UX design", - skills=["JavaScript", "React", "HTML5", "CSS3"], - experience_level="Expert", - tools=["VS Code", "webpack", "npm", "Chrome DevTools"], - llm=llm - ), - LLMTaskAgent( - name="DevOps", - context="DevOps and infrastructure management", - skills=["CI/CD", "Cloud infrastructure", "Containerization", "Monitoring"], - experience_level="Expert", - tools=["Jenkins", "AWS", "Docker", "Kubernetes"], - llm=llm - ), - LLMTaskAgent( - name="DataAnalyst", - context="Data analysis and statistics", - skills=["Data visualization", "Statistical analysis", "SQL", "Excel"], - experience_level="Advanced", - tools=["Tableau", "R", "Python", "Microsoft Excel"], - llm=llm - ), - LLMTaskAgent( - name="DataScientist", - context="Data science and machine learning", - skills=["Machine learning", "Deep learning", "NLP", "Big data"], - experience_level="Expert", - tools=["Python", "TensorFlow", "Scikit-learn", "Jupyter Notebook"], - llm=llm - ), - LLMTaskAgent( - name="QATester", - context="Software testing and quality assurance", - skills=["Manual testing", "Automated testing", "Performance testing", "Security testing"], - experience_level="Advanced", - tools=["Selenium", "JUnit", "JIRA", "Postman"], - llm=llm - ) - ] - - # Create and run task manager - task_manager = LLMTaskManager(tasks, specialized_agents) - task_manager.run_admin(inputs=b"", workers=specialized_agents) diff --git a/bindings/ceylon/tests/llm_agents/task_manager-ollama.py b/bindings/ceylon/tests/llm_agents/task_manager-ollama.py deleted file mode 100644 index ebab6e70..00000000 --- a/bindings/ceylon/tests/llm_agents/task_manager-ollama.py +++ /dev/null @@ -1,129 +0,0 @@ -import asyncio -import os -from typing import List - -from langchain.chains.llm import LLMChain -from langchain_community.chat_models import ChatOllama -from langchain_core.prompts import ChatPromptTemplate -from langchain_openai import ChatOpenAI -from loguru import logger -from openai import OpenAI -from pydantic.dataclasses import dataclass - -from ceylon import Agent, CoreAdmin, on_message - -# Ensure you set your OpenAI API key as an environment variable -client = OpenAI( - # This is the default and can be omitted - api_key=os.environ.get("OPENAI_API_KEY"), -) - - -@dataclass -class Task: - id: int - description: str - - -@dataclass -class TaskAssignment: - task: Task - assigned_agent: str - - -@dataclass -class TaskResult: - task_id: int - agent: str - result: str - - -class SpecializedAgent(Agent): - def __init__(self, name: str, specialty: str): - self.specialty = specialty - super().__init__(name=name, workspace_id="openai_task_management", admin_peer="TaskManager", admin_port=8000) - - @on_message(type=TaskAssignment) - async def on_task_assignment(self, data: TaskAssignment): - if data.assigned_agent == self.details().name: - logger.info(f"{self.details().name} received task: {data.task.description}") - # Simulate task execution - await asyncio.sleep(2) - result = f"{self.details().name} completed the task: {data.task.description}" - await self.broadcast_data(TaskResult(task_id=data.task.id, agent=self.details().name, result=result)) - - -class TaskManager(CoreAdmin): - tasks: List[Task] = [] - agents: List[SpecializedAgent] = [] - results: List[TaskResult] = [] - - def __init__(self, tasks: List[Task], agents: List[SpecializedAgent]): - self.tasks = tasks - self.agents = agents - super().__init__(name="openai_task_management", port=8000) - - async def run(self, inputs: bytes): - await self.assign_tasks() - - async def assign_tasks(self): - for task in self.tasks: - assigned_agent = await self.get_best_agent_for_task(task) - print(f"Assigned task {task.id} to agent {assigned_agent}") - await self.broadcast_data(TaskAssignment(task=task, assigned_agent=assigned_agent)) - - async def get_best_agent_for_task(self, task: Task) -> str: - agent_specialties = "\n".join([f"{agent.details().name}: {agent.specialty}" for agent in self.agents]) - # Initialize the language model - llm = ChatOllama(model="llama3.1:latest", temperature=0) - - # Create a prompt template - prompt_template = ChatPromptTemplate.from_template( - """Given the following task and list of agents with their specialties, determine which agent is - best suited for the task. - - Task: {task_description} - - Agents and their specialties: - {agent_specialties} - - Respond with only the name of the best-suited agent.""" - ) - - # Create the chain - chain = LLMChain(llm=llm, prompt=prompt_template) - response = chain.run(task_description=task.description, agent_specialties=agent_specialties) - return response.strip() - - @on_message(type=TaskResult) - async def on_task_result(self, result: TaskResult): - self.results.append(result) - logger.info(f"Received result for task {result.task_id} from {result.agent}: {result.result}") - if len(self.results) == len(self.tasks): - await self.end_task_management() - - async def end_task_management(self): - logger.info("All tasks completed. Results:") - for result in self.results: - logger.info(f"Task {result.task_id}: {result.result}") - await self.stop() - - -if __name__ == "__main__": - # Create tasks - tasks = [ - Task(id=1, description="Analyze recent stock market trends"), - Task(id=2, description="Debug a Python web application"), - Task(id=3, description="Write a press release for a new product launch"), - ] - - # Create specialized agents - agents = [ - SpecializedAgent("FinanceExpert", "Financial analysis and stock market trends"), - SpecializedAgent("SoftwareDeveloper", "Programming, debugging, and software development"), - SpecializedAgent("ContentWriter", "Writing, editing, and content creation"), - ] - - # Create and run task manager - task_manager = TaskManager(tasks, agents) - task_manager.run_admin(inputs=b"", workers=agents) diff --git a/bindings/ceylon/tests/llm_agents/task_manager-open-ai.py b/bindings/ceylon/tests/llm_agents/task_manager-open-ai.py deleted file mode 100644 index 0293e466..00000000 --- a/bindings/ceylon/tests/llm_agents/task_manager-open-ai.py +++ /dev/null @@ -1,128 +0,0 @@ -import asyncio -import os -from typing import List - -from loguru import logger -from openai import OpenAI -from pydantic.dataclasses import dataclass - -from ceylon import Agent, CoreAdmin, on_message - -# Ensure you set your OpenAI API key as an environment variable -client = OpenAI( - # This is the default and can be omitted - api_key=os.environ.get("OPENAI_API_KEY"), -) - - -@dataclass -class Task: - id: int - description: str - - -@dataclass -class TaskAssignment: - task: Task - assigned_agent: str - - -@dataclass -class TaskResult: - task_id: int - agent: str - result: str - - -class SpecializedAgent(Agent): - def __init__(self, name: str, specialty: str): - self.specialty = specialty - super().__init__(name=name, workspace_id="openai_task_management", admin_peer="TaskManager", admin_port=8000) - - @on_message(type=TaskAssignment) - async def on_task_assignment(self, data: TaskAssignment): - if data.assigned_agent == self.details().name: - logger.info(f"{self.details().name} received task: {data.task.description}") - # Simulate task execution - await asyncio.sleep(2) - result = f"{self.details().name} completed the task: {data.task.description}" - await self.broadcast_data(TaskResult(task_id=data.task.id, agent=self.details().name, result=result)) - - -class TaskManager(CoreAdmin): - tasks: List[Task] = [] - agents: List[SpecializedAgent] = [] - results: List[TaskResult] = [] - - def __init__(self, tasks: List[Task], agents: List[SpecializedAgent]): - self.tasks = tasks - self.agents = agents - super().__init__(name="openai_task_management", port=8000) - - async def run(self, inputs: bytes): - await self.assign_tasks() - - async def assign_tasks(self): - for task in self.tasks: - assigned_agent = await self.get_best_agent_for_task(task) - await self.broadcast_data(TaskAssignment(task=task, assigned_agent=assigned_agent)) - - async def get_best_agent_for_task(self, task: Task) -> str: - agent_specialties = "\n".join([f"{agent.details().name}: {agent.specialty}" for agent in self.agents]) - prompt = f"""Given the following task and list of agents with their specialties, determine which agent is - best suited for the task. - - Task: {task.description} - - Agents and their specialties: - {agent_specialties} - - Respond with only the name of the best-suited agent.""" - - response = client.chat.completions.create( - model="gpt-4o-mini", - messages=[ - {"role": "system", - "content": "You are an AI assistant that helps assign tasks to" - " the most suitable agent based on their specialties."}, - {"role": "user", "content": prompt} - ] - ) - - best_agent = response.choices[0].message.content.strip() - print(f"Best agent: {best_agent}") - logger.info(f"OpenAI suggests assigning task '{task.description}' to agent '{best_agent}'") - return best_agent - - @on_message(type=TaskResult) - async def on_task_result(self, result: TaskResult): - self.results.append(result) - logger.info(f"Received result for task {result.task_id} from {result.agent}: {result.result}") - if len(self.results) == len(self.tasks): - await self.end_task_management() - - async def end_task_management(self): - logger.info("All tasks completed. Results:") - for result in self.results: - logger.info(f"Task {result.task_id}: {result.result}") - await self.stop() - - -if __name__ == "__main__": - # Create tasks - tasks = [ - Task(id=1, description="Analyze recent stock market trends"), - Task(id=2, description="Debug a Python web application"), - Task(id=3, description="Write a press release for a new product launch"), - ] - - # Create specialized agents - agents = [ - SpecializedAgent("FinanceExpert", "Financial analysis and stock market trends"), - SpecializedAgent("SoftwareDeveloper", "Programming, debugging, and software development"), - SpecializedAgent("ContentWriter", "Writing, editing, and content creation"), - ] - - # Create and run task manager - task_manager = TaskManager(tasks, agents) - task_manager.run_admin(inputs=b"", workers=agents) diff --git a/bindings/ceylon/tests/llm_agents/tasks_with_dependencies.py b/bindings/ceylon/tests/llm_agents/tasks_with_dependencies.py deleted file mode 100644 index 144a7280..00000000 --- a/bindings/ceylon/tests/llm_agents/tasks_with_dependencies.py +++ /dev/null @@ -1,124 +0,0 @@ -import asyncio -from typing import List, Dict, Any - -from pydantic.dataclasses import dataclass -from pydantic.v1 import BaseModel - -from ceylon import Agent, CoreAdmin, on_message -from loguru import logger - - -class Task(BaseModel): - id: int - description: str - difficulty: int # 1-10 scale - dependencies: List[int] # List of task IDs this task depends on - - -class SubTask(BaseModel): - task: Task - assigned_worker: str - - -class TaskAssignment(BaseModel): - subtask: SubTask - - -@dataclass -class TaskResult: - task_id: int - worker: str - success: bool - - -class WorkerAgent(Agent): - def __init__(self, name: str, skill_level: int): - self.name = name - self.skill_level = skill_level - super().__init__(name=name, workspace_id="advanced_task_management", admin_port=8000) - - @on_message(type=TaskAssignment) - async def on_task_assignment(self, data: TaskAssignment): - logger.info(f"{self.name} received task: {data.subtask.task.description}") - # Simulate task execution - await asyncio.sleep(data.subtask.task.difficulty) - success = self.skill_level >= data.subtask.task.difficulty - await self.broadcast_data(TaskResult(task_id=data.subtask.task.id, worker=self.name, success=success)) - - -class TaskManager(CoreAdmin): - tasks: List[Task] = [] - workers: List[WorkerAgent] = [] - task_results: Dict[int, TaskResult] = {} - pending_tasks: Dict[int, Any] = {} - completed_tasks: List[int] = [] - - def __init__(self, tasks: List[Task], workers: List[WorkerAgent]): - self.tasks = tasks - self.workers = workers - self.pending_tasks = {task.id: SubTask(task=task, assigned_worker="") for task in tasks} - super().__init__(name="advanced_task_management", port=8000) - - async def on_agent_connected(self, topic: str, agent_id: str): - logger.info(f"Worker {agent_id} connected") - # if len(self.workers) == len(self.tasks): - await self.assign_tasks() - - async def assign_tasks(self): - for task_id, subtask in self.pending_tasks.items(): - if all(dep in self.completed_tasks for dep in subtask.task.dependencies): - available_worker = next((w for w in self.workers if w.skill_level >= subtask.task.difficulty), None) - if available_worker: - subtask.assigned_worker = available_worker.name - await self.broadcast_data(TaskAssignment(subtask=subtask)) - logger.info(f"Assigned task {task_id} to {available_worker.name}") - - @on_message(type=TaskResult) - async def on_task_result(self, result: TaskResult): - self.task_results[result.task_id] = result - self.completed_tasks.append(result.task_id) - logger.info( - f"Received result for task {result.task_id} from {result.worker}: {'Success' if result.success else 'Failure'}") - - # Remove the completed task from pending tasks - print("self.pending_tasks[result.task_id]", result.task_id, result.task_id in self.pending_tasks) - if result.task_id in self.pending_tasks: - print("del self.pending_tasks[result.task_id]", result.task_id) - del self.pending_tasks[result.task_id] - # print(self.pending_tasks) - # for idx, task in self.pending_tasks: - # if task.task_id == result.task_id: - # del self.pending_tasks[idx] - - # Check if we can assign more tasks - await self.assign_tasks() - - if not self.pending_tasks: - await self.end_task_management() - - async def end_task_management(self): - success_rate = sum(1 for result in self.task_results.values() if result.success) / len(self.task_results) - logger.info(f"All tasks completed. Success rate: {success_rate:.2%}") - await self.stop() - - -if __name__ == '__main__': - # Create tasks with dependencies - tasks = [ - Task(id=1, description="Data preparation", difficulty=2, dependencies=[]), - Task(id=2, description="Feature engineering", difficulty=5, dependencies=[1]), - Task(id=3, description="Model training", difficulty=8, dependencies=[2]), - Task(id=4, description="Model evaluation", difficulty=6, dependencies=[3]), - Task(id=5, description="Report generation", difficulty=4, dependencies=[4]), - ] - - # Create workers - workers = [ - WorkerAgent("Junior", skill_level=3), - WorkerAgent("Intermediate", skill_level=6), - WorkerAgent("Senior", skill_level=9), - ] - - # Create and run task manager - task_manager = TaskManager(tasks, workers) - task_manager.run_admin(inputs=b"", workers=workers) diff --git a/bindings/ceylon/tests/llm_test/__init__.py b/bindings/ceylon/tests/llm_test/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/tests/llm_test/llm_test_open_ai.py b/bindings/ceylon/tests/llm_test/llm_test_open_ai.py deleted file mode 100644 index 097f36d7..00000000 --- a/bindings/ceylon/tests/llm_test/llm_test_open_ai.py +++ /dev/null @@ -1,67 +0,0 @@ -from ceylon.llm import LLMTaskCoordinator, LLMTaskOperator - -from langchain_openai import ChatOpenAI - -code_llm = ChatOpenAI(model="gpt-4o") - -python_developer = LLMTaskOperator( - name="python_developer", - role="Junior Python Developer", - context="Develop Python application with standalone application development knowlage", - skills=[ - "Python programming" - ], - llm=code_llm -) - -python_gui_developer = LLMTaskOperator( - name="python_gui_developer", - role="Junior Python GUI Developer", - context="Develop Python application with GUI development knowlage", - skills=[ - "Python programming", - "GUI development" - ], - llm=code_llm -) - -from ceylon.task import Task - -task = Task( - name="Create Task Management App", - description="Develop a advance task manager app. Required features. mark completed, filter with date, download by selected date. Need a UI for users" -) - -tool_llm = ChatOpenAI(model="gpt-4o-mini") -llm = ChatOpenAI(model="gpt-4o-mini") - -from textwrap import dedent - -agents = [python_developer, python_gui_developer] - -software_agency = LLMTaskCoordinator( - tasks=[task], - agents=agents, - team_goal=dedent(""" - Develop and deliver straightforward, secure, and efficient Python-based - software solutions that provide clear business value, - achieve 95% client satisfaction, and are completed on time and within budget - """), - context=dedent(""" - Employ agile methodologies to gather and analyze client requirements, design simple yet - robust solutions, implement clean and readable Python code, conduct thorough testing, - and deploy using streamlined CI/CD practices. Prioritize code simplicity, - maintainability, and adherence to Python best practices - throughout the development lifecycle, following the principle that - 'simple is better than complex'. - """), - llm=llm, - tool_llm=tool_llm -) - -completed_tasks = software_agency.do() -# Print results -for task in completed_tasks: - print(f"Task: {task.name}") - print(f"Result: {task.final_answer}") - print("-" * 50) diff --git a/bindings/ceylon/tests/llm_test/llm_writer.py b/bindings/ceylon/tests/llm_test/llm_writer.py deleted file mode 100644 index 862d7b12..00000000 --- a/bindings/ceylon/tests/llm_test/llm_writer.py +++ /dev/null @@ -1,85 +0,0 @@ -from langchain_community.chat_models import ChatOllama - -from ceylon import JobSteps, Step, JobRequest -from ceylon.llm import LLMAgent -from ceylon.llm.llm_task_operator import LLMExecutorAgent -from ceylon.tools.search_tool import SearchTool - -llm_lib = ChatOllama(model="llama3.1:latest") -# llm_lib = ChatOpenAI(model="gpt-4o") -researcher = LLMAgent( - name="researcher", - role="AI and Machine Learning Research Specialist", - objective="Search from web for relevant information with source references", - context="Searches for relevant information on web to gather data for content creation", - tools=[ - SearchTool() - ], - llm=llm_lib -) - -writer = LLMAgent( - name="writer", - role="Content Writer", - objective="Increase engagement and improve public understanding of the topic.", - context="Simplifies technical concepts with metaphors, and creates narrative-driven " - "content while ensuring scientific accuracy.", - llm=llm_lib -) - -seo_optimizer = LLMAgent( - name="seo_optimizer", - role="SEO Optimizer", - objective="Optimize content for search engines", - context="Optimize content for search engines, with SEO optimization. You will optimize " - "the content for search engines.", - tools=[], - llm=llm_lib -) -proof_writer = LLMAgent( - name="proof_writer", - role="Proof Writer", - objective="Increase engagement and improve public understanding of the topic.", - context="Simplifies technical concepts with paraphrasing, and creates narrative-driven content " - "while ensuring scientific accuracy." - " Proof writer will proofread and proofread the content. Do not use any explanation just use final article", - llm=llm_lib -) -job = JobRequest( - title="write_article", - steps=JobSteps(steps=[ - Step( - worker="seo_optimizer", - dependencies=["writer"], - ), - Step( - worker="researcher", - dependencies=[], - ), - Step( - worker="writer", - dependencies=["researcher"], - ), - Step( - worker="proof_writer", - dependencies=["seo_optimizer"], - ) - ]), - job_data="Write Article Title: What is the importance of Machine Learning, Tone: Informal, " - "Style: Creative, Length: Large. Focus on keyword AI,Future", -) - -coordinator = LLMExecutorAgent(workers=[researcher, writer, seo_optimizer, proof_writer]) - - -# res: JobRequest = coordinator.execute(job) -# print("Response:", res) -async def main(): - res: JobRequest = await coordinator.aexecute(job) - print("Response:", res) - - -if __name__ == '__main__': - import asyncio - - asyncio.run(main()) diff --git a/bindings/ceylon/tests/llm_test/stock_analyser.py b/bindings/ceylon/tests/llm_test/stock_analyser.py deleted file mode 100644 index be847440..00000000 --- a/bindings/ceylon/tests/llm_test/stock_analyser.py +++ /dev/null @@ -1,83 +0,0 @@ -from time import sleep - -from langchain_community.chat_models import ChatOllama - -from ceylon import Agent, AgentJobStepRequest, AgentJobResponse, JobRequest, JobSteps, Step, RunnerAgent - -llm_lib = ChatOllama(model="llama3:instruct") - - -class TAAgent(Agent): - - async def execute_request(self, request: AgentJobStepRequest) -> AgentJobResponse: - return AgentJobResponse( - worker=self.details().name, - job_data={ - "MA": 100.0, - "EMA": 200.0, - } - ) - - -class NewAnalysisAgent(Agent): - - async def execute_request(self, request: AgentJobStepRequest) -> AgentJobResponse: - return AgentJobResponse( - worker=self.details().name, - job_data={ - "sentiment": "Positive", - } - ) - - -class DecisionMakerAgent(Agent): - - async def execute_request(self, request: AgentJobStepRequest) -> AgentJobResponse: - return AgentJobResponse( - worker=self.details().name, - job_data={ - "job": request.job_id, - "trade": True, - } - ) - - -ta_worker = TAAgent(name="ta", role="Technical Analyst") -ta_worker2 = TAAgent(name="ta2", role="Technical Analyst2") -ta_worker3 = TAAgent(name="ta2", role="Technical Analyst3") -news_sentiment_worker = NewAnalysisAgent(name="news_sentiment", role="Technical Analyst") -decision_maker_worker = DecisionMakerAgent(name="decision_maker", role="Make Decision") - -chief = RunnerAgent(workers=[ta_worker, ta_worker2, ta_worker3, news_sentiment_worker, decision_maker_worker], - tool_llm=llm_lib, - parallel_jobs=1, - server_mode=False) - -job = JobRequest( - title=f"{10} write_article", - explanation="Write an article about machine learning, Tone: Informal, Style: Creative, Length: Large", - steps=JobSteps(steps=[ - Step( - worker="ta", - explanation="", - dependencies=[] - ), - Step( - worker="ta2", - explanation="", - dependencies=[] - ), - Step( - worker="news_sentiment", - explanation="", - dependencies=["ta2"] - ), - Step( - worker="decision_maker", - explanation="", - dependencies=["ta", "news_sentiment"] - ) - ]) -) -res = chief.execute(job) -print("Finished job: ", job.id, job.current_status, res.id) diff --git a/bindings/ceylon/tests/llm_test/stock_analyser_async.py b/bindings/ceylon/tests/llm_test/stock_analyser_async.py deleted file mode 100644 index 1b47db90..00000000 --- a/bindings/ceylon/tests/llm_test/stock_analyser_async.py +++ /dev/null @@ -1,85 +0,0 @@ -import asyncio -import threading - -from ceylon.agent.types.agent_request import AgentJobStepRequest, AgentJobResponse -from ceylon.agent.types.job import JobRequest, JobSteps, Step -from ceylon.agent.agents import RunnerAgent, Agent -from langchain_community.chat_models import ChatOllama - -llm_lib = ChatOllama(model="llama3:instruct") - - -class TAAgent(Agent): - - async def execute_request(self, request: AgentJobStepRequest) -> AgentJobResponse: - return AgentJobResponse( - worker=self.details().name, - job_data={ - "MA": 100.0, - "EMA": 200.0, - } - ) - - -class NewAnalysisAgent(Agent): - - async def execute_request(self, request: AgentJobStepRequest) -> AgentJobResponse: - return AgentJobResponse( - worker=self.details().name, - job_data={ - "sentiment": "Positive", - } - ) - - -class DecisionMakerAgent(Agent): - - async def execute_request(self, request: AgentJobStepRequest) -> AgentJobResponse: - return AgentJobResponse( - worker=self.details().name, - job_data={ - "trade": True, - } - ) - - -ta_worker = TAAgent(name="ta", role="Technical Analyst") -news_sentiment_worker = NewAnalysisAgent(name="news_sentiment", role="Technical Analyst") -decision_maker_worker = DecisionMakerAgent(name="decision_maker", role="Make Decision") - -chief = RunnerAgent(workers=[ta_worker, news_sentiment_worker, decision_maker_worker], tool_llm=llm_lib, - server_mode=True, parallel_jobs=5) -threading.Thread(target=chief.execute, args=({})).start() - - -async def main(): - for i in range(10): - async def on_success_callback(res: AgentJobResponse, job: JobRequest): - print("Finished job: ", res, res.job_id, job.id) - - job = JobRequest( - title=f"{i} write_article", - explanation="Write an article about machine learning, Tone: Informal, Style: Creative, Length: Large", - steps=JobSteps(steps=[ - Step( - worker="ta", - explanation="", - dependencies=[] - ), - Step( - worker="news_sentiment", - explanation="", - dependencies=[] - ), - Step( - worker="decision_maker", - explanation="", - dependencies=["ta", "news_sentiment"] - ) - ]), - on_success_callback=on_success_callback - ) - await chief.add_job(job) - - -asyncio.run(main()) diff --git a/bindings/ceylon/tests/server_agents/__init__.py b/bindings/ceylon/tests/server_agents/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/tests/server_agents/agent_one.py b/bindings/ceylon/tests/server_agents/agent_one.py deleted file mode 100644 index f3a4fcdc..00000000 --- a/bindings/ceylon/tests/server_agents/agent_one.py +++ /dev/null @@ -1,46 +0,0 @@ -import asyncio -import pickle -import random -import time -from typing import Any - -from loguru import logger -from pydantic import BaseModel - -from ceylon import on_message -from ceylon.ceylon import enable_log -from ceylon.static_val import DEFAULT_CONF_FILE -from ceylon.task import TaskOperator - -# enable_log("INFO") - - -class SubTaskMessage(BaseModel): - message: str - time: float - - -class SubTaskWorkingAgent(TaskOperator): - async def get_result(self, task) -> Any: - return "done" - - @on_message(type=SubTaskMessage) - async def on_sub_task_message(self, data: SubTaskMessage): - logger.info(f"Got message: {data}") - - async def run(self, inputs: "bytes"): - while True: - await self.broadcast_data(SubTaskMessage(message="hello", time=time.time())) - logger.info("done") - random_number = random.randint(1, 10) - await asyncio.sleep(random_number) - - async def on_agent_connected(self, topic: "str", agent: "AgentDetail"): - logger.info(f"Agent {agent.name} connected to {topic}") - await super().on_agent_connected(topic, agent) - - -worker_1 = SubTaskWorkingAgent("worker_2", "server_admin", - conf_file=DEFAULT_CONF_FILE) - -asyncio.run(worker_1.arun_worker(pickle.dumps({}))) diff --git a/bindings/ceylon/tests/server_agents/monitor_agent.py b/bindings/ceylon/tests/server_agents/monitor_agent.py deleted file mode 100644 index 4f23fb8b..00000000 --- a/bindings/ceylon/tests/server_agents/monitor_agent.py +++ /dev/null @@ -1,75 +0,0 @@ -import asyncio -import pickle -from datetime import datetime - -import socketio -from fastapi import FastAPI -from loguru import logger -from pydantic import BaseModel, Field -from starlette.middleware.cors import CORSMiddleware -from uvicorn import Config, Server - -from ceylon import Agent -from ceylon.ceylon import enable_log - -app = FastAPI() -origins = ["*"] -app.add_middleware(CORSMiddleware, - allow_origins=origins, - allow_credentials=True, - allow_methods=["*"], - allow_headers=["*"], - ) - -sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins='*') - -sio_asgi_app = socketio.ASGIApp(socketio_server=sio, other_asgi_app=app) - - -class Message(BaseModel): - message: str = Field(min_length=1, max_length=100) - sender: str = Field(min_length=1, max_length=100) - time: datetime = Field(default_factory=datetime.now) - type: str = Field(min_length=1, max_length=100) - - -class TaskMonitorAgent(Agent): - - async def on_message(self, agent_id: "str", data: "bytes", time: "int"): - logger.info(f"Monitor Agent Got message: {data}") - - async def run(self, inputs: "bytes"): - @app.get("/") - async def read_root(): - return {"message": "Hello World"} - - @app.post("/api/chat") - async def send_message(message: Message): - await self.broadcast_data(message) - logger.info(f"Sent message: {message}") - - # Example Socket.IO event handler - @sio.event - async def connect(sid, environ): - pass - - @sio.event - async def disconnect(sid): - logger.debug(f"Client disconnected: {sid}") - - # Start the Socket.IO server - - config = Config(app=sio_asgi_app, host="0.0.0.0", port=7878, log_level="error") - server = Server(config) - await server.serve() - - -task_monitor = TaskMonitorAgent(name="worker_2", - role="server_admin", - admin_port=8888, - workspace_id="ceylon_agent_stack", - admin_ip="23.94.182.52", - admin_peer="12D3KooWEUH7vcsHUQ72xfExPZLHawWiYZrybZL5Hj9t6RvkcHpX") - -enable_log("INFO") -asyncio.run(task_monitor.arun_worker(pickle.dumps({}))) diff --git a/bindings/ceylon/tests/server_agents/server_agent.py b/bindings/ceylon/tests/server_agents/server_agent.py deleted file mode 100644 index 09428e2e..00000000 --- a/bindings/ceylon/tests/server_agents/server_agent.py +++ /dev/null @@ -1,9 +0,0 @@ -import asyncio - -from ceylon.ceylon import enable_log -from ceylon.task import TaskCoordinator - -task_manager = TaskCoordinator(tasks=[], agents=[]) - -enable_log("INFO") -asyncio.run(task_manager.async_do()) diff --git a/bindings/ceylon/tests/single_llm_agent.py b/bindings/ceylon/tests/single_llm_agent.py deleted file mode 100644 index e8c5f680..00000000 --- a/bindings/ceylon/tests/single_llm_agent.py +++ /dev/null @@ -1,49 +0,0 @@ -import asyncio - -from langchain_community.chat_models import ChatOllama - -from ceylon import AgentRunner -from ceylon.llm.llm_agent import LLMAgent - - -async def main(): - runner = AgentRunner(workspace_name="ceylon-ai") - llm_lib = ChatOllama(model="llama3:instruct") - # llm_lib = ChatOpenAI(model="gpt-4o") - runner.register_agent(LLMAgent( - name="writer", - position="Assistant Writer", - llm=llm_lib, - responsibilities=["Create high-quality, original content that matches the audience's tone and style."], - instructions=[ - "Ensure clarity, accuracy, and proper formatting while respecting ethical guidelines and privacy."] - )) - runner.register_agent(LLMAgent( - name="resercher", - position="Assistant Writer", - llm=llm_lib, - responsibilities=["Create high-quality, original content that matches the audience's tone and style."], - instructions=[ - "Ensure clarity, accuracy, and proper formatting while respecting ethical guidelines and privacy."] - )) - - await runner.run( - { - "request": "I want to create a blog post", - "title": "How to use AI for Machine Learning", - "tone": "informal", - "length": "large", - "style": "creative" - }, - network={ - "name_chooser": [], - "researcher": [], - "writer": ["researcher"], - "editor": ["writer"], - "publisher": ["editor", "name_chooser"] - } - ) - - -if __name__ == '__main__': - asyncio.run(main()) diff --git a/bindings/ceylon/tests/stm/__init__.py b/bindings/ceylon/tests/stm/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/tests/stm/agent_stm.py b/bindings/ceylon/tests/stm/agent_stm.py deleted file mode 100644 index d98bc0aa..00000000 --- a/bindings/ceylon/tests/stm/agent_stm.py +++ /dev/null @@ -1,23 +0,0 @@ -from ceylon.auto.manager.agent_taskmanager import AgentTaskManager -from ceylon.auto.worker.agent_executor import TaskExecutorAgent - -workspace_id = "ceylon-stm-task-manager" -agent_mgt = AgentTaskManager(name=workspace_id, ) - -agent_mgt.register_agent(TaskExecutorAgent( - workspace_id=workspace_id, - name="executor_agent1", - role="executor_1", -)) -agent_mgt.register_agent(TaskExecutorAgent( - workspace_id=workspace_id, - name="executor_agent2", - role="executor_2", -)) -agent_mgt.register_agent(TaskExecutorAgent( - workspace_id=workspace_id, - name="executor_agent3", - role="executor_3", -)) - -agent_mgt.do() diff --git a/bindings/ceylon/tests/stm/main.py b/bindings/ceylon/tests/stm/main.py deleted file mode 100644 index 7ac8a73b..00000000 --- a/bindings/ceylon/tests/stm/main.py +++ /dev/null @@ -1,72 +0,0 @@ -# Create a new subtask that requires inputs -from ceylon.auto.manager.cli_manager import CLI_TaskManager -from ceylon.auto.model import SubTask, Task - -# SubTask 1: Market Research -market_research = SubTask( - name="Market Research", - executor="Alice", - needs_approval=False, - inputs_needed=["Target Demographics", "Market Trends"] -) - -# SubTask 2: Design Prototype -design_prototype = SubTask( - name="Design Prototype", - executor="Bob", - needs_approval=False, # Auto-approves since needs_approval is False - dependencies=[market_research] -) - -# SubTask 3: User Testing -user_testing = SubTask( - name="User Testing", - executor="Charlie", - needs_approval=True, - dependencies=[design_prototype] -) - -# SubTask 4: Finalize Product -finalize_product = SubTask( - name="Finalize Product", - executor="Diana", - needs_approval=False, - dependencies=[user_testing], - inputs_needed=["Final Specifications"] -) - -# SubTask 5: Marketing Campaign -marketing_campaign = SubTask( - name="Marketing Campaign", - executor="Ethan", - needs_approval=True, - dependencies=[finalize_product] -) - -# SubTask 6: Launch Event -launch_event = SubTask( - name="Launch Event", - executor="Fiona", - needs_approval=False, - dependencies=[marketing_campaign] -) - -# Create the main task -launch_product_task = Task( - name="Launch New Product", - subtasks=[ - market_research, - design_prototype, - user_testing, - finalize_product, - marketing_campaign, - launch_event - ] -) - -# Add the task to the manager and run -task_manager = CLI_TaskManager() -task_manager.add_task(launch_product_task) - -while not task_manager.all_tasks_completed(): - task_manager.progress_tasks() diff --git a/bindings/ceylon/tests/tasks/__init__.py b/bindings/ceylon/tests/tasks/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/tests/tasks/article-writer-agents-gen-with-tools-openai.py b/bindings/ceylon/tests/tasks/article-writer-agents-gen-with-tools-openai.py deleted file mode 100644 index f8a56ede..00000000 --- a/bindings/ceylon/tests/tasks/article-writer-agents-gen-with-tools-openai.py +++ /dev/null @@ -1,167 +0,0 @@ -from typing import Optional, Type - -from langchain.pydantic_v1 import BaseModel, Field -from langchain_core.callbacks import ( - AsyncCallbackManagerForToolRun, - CallbackManagerForToolRun, -) -from langchain_core.tools import BaseTool -from langchain_openai import ChatOpenAI -from loguru import logger - -from ceylon.task import Task - - -class QueryInput(BaseModel): - prompt: str = Field(description="Input prompt") - - -class ImageGenerationTool(BaseTool): - name = "ImageGenerationTool" - description = "Useful for when you need to generate an image. Input should be a description of what you want to generate." - args_schema: Type[BaseModel] = QueryInput - return_direct: bool = True - - def _run( - self, query: str, run_manager: Optional[CallbackManagerForToolRun] = None - ) -> str: - """Use the tool.""" - logger.info(f"Processing query: {query}") - # This is a simple example. You can replace this with more complex logic. - return f"https://cdn.pixabay.com/photo/2024/01/02/10/33/stream-8482939_1280.jpg" - - async def _arun( - self, - query: str, - run_manager: Optional[AsyncCallbackManagerForToolRun] = None, - ) -> str: - """Use the tool asynchronously.""" - # For this example, we're delegating to the sync implementation. - # If the processing is expensive, you might want to implement a truly - # asynchronous version or remove this method entirely. - return self._run(query, run_manager=run_manager.get_sync() if run_manager else None) - - -# Example usage -if __name__ == "__main__": - # Create a task with initial subtasks - article_task = Task(name="Write Article", - description="Write an article about AI advancements. The final output should strictly include only the title and the content and cover image, without any additional sections or formatting.") - - tasks = [ - article_task - ] - - llm = ChatOpenAI(model="gpt-4o-mini") - tool_llm = ChatOpenAI(model="gpt-4o-mini") - - # llm = ChatOllama(model="llama3.1:latest") - # tool_llm = OllamaFunctions(model="llama3.1:latest", format="json") - - # Create specialized agents - agents = [ - LLMTaskAgent( - name="research", - role="Online search things", - context="Can search for facts and points on the internet in a variety of ways.", - skills=[ - "Search online", - "Keyword Research", - "Online Research", - "Research", - "Researching", - "Researcher", - ], - tools=[], - llm=llm, - tool_llm=tool_llm - ), - LLMTaskAgent( - name="image_generation", - role="Image Generation", - context="Can generate images from text.", - skills=[ - "Image Generation", - ], - tools=[ - ImageGenerationTool() - ], - llm=llm, - tool_llm=tool_llm - ), - - LLMTaskAgent( - name="writing", - role="Content Strategist & Writer", - context="Deep understanding of various writing styles, content formats, " - "and audience engagement strategies. Knowledgeable about " - "SEO-friendly writing, storytelling techniques, and brand voice " - "development. Familiar with content management systems and digital publishing platforms.", - skills=[ - "Creative Writing", - "Technical Writing", - "Copywriting", - "Content Strategy", - "Storytelling", - "SEO Writing", - "Editing and Proofreading", - "Brand Voice Development", - "Audience Analysis", - "Multimedia Content Creation" - ], - tools=[], - llm=llm - ), - - LLMTaskAgent( - name="seo_optimization", - role="SEO Strategist", - context="Comprehensive understanding of search engine algorithms," - " ranking factors, and SEO best practices. Proficient in technical SEO," - " content optimization, and link building strategies. Familiar with local SEO," - " mobile optimization, and voice search optimization.", - skills=[ - "Keyword Research", - "On-Page SEO", - "Off-Page SEO", - "Technical SEO", - "Content Optimization", - "Link Building", - "Local SEO", - "Mobile SEO", - "Voice Search Optimization", - "SEO Analytics and Reporting" - ], - tools=[], - llm=llm - ), - - LLMTaskAgent( - name="web_publishing", - role="Digital Content Manager", - context="Extensive knowledge of web publishing platforms, " - "content management systems, and digital asset management. " - "Proficient in HTML, CSS, and basic JavaScript. Familiar with web accessibility standards, " - "responsive design principles, and UX/UI best practices.", - skills=[ - "CMS Management", - "HTML/CSS", - "Content Scheduling", - "Digital Asset Management", - "Web Accessibility", - "Responsive Design", - "Version Control", - "A/B Testing", - "Web Analytics", - "User Experience Optimization" - ], - tools=[], - llm=llm - ) - ] - - task_manager = LLMTaskManager(tasks, agents, tool_llm=tool_llm, llm=llm) - tasks = task_manager.do(inputs=b"") - - for t in tasks: - print(t.final_answer) diff --git a/bindings/ceylon/tests/tasks/article-writer-agents-gen-with-tools.py b/bindings/ceylon/tests/tasks/article-writer-agents-gen-with-tools.py deleted file mode 100644 index 561f8ef8..00000000 --- a/bindings/ceylon/tests/tasks/article-writer-agents-gen-with-tools.py +++ /dev/null @@ -1,166 +0,0 @@ -from typing import Optional, Type - -from langchain.pydantic_v1 import BaseModel, Field -from langchain_community.chat_models import ChatOllama -from langchain_core.callbacks import ( - AsyncCallbackManagerForToolRun, - CallbackManagerForToolRun, -) -from langchain_core.tools import BaseTool -from langchain_experimental.llms.ollama_functions import OllamaFunctions -from loguru import logger - -from ceylon.llm import LLMTaskOperator, LLMTaskCoordinator -from ceylon.task import Task - - -class QueryInput(BaseModel): - prompt: str = Field(description="Input prompt") - - -class ImageGenerationTool(BaseTool): - name = "ImageGenerationTool" - description = "Useful for when you need to generate an image. Input should be a description of what you want to generate." - args_schema: Type[BaseModel] = QueryInput - return_direct: bool = True - - def _run( - self, query: str, run_manager: Optional[CallbackManagerForToolRun] = None - ) -> str: - """Use the tool.""" - logger.info(f"Processing query: {query}") - # This is a simple example. You can replace this with more complex logic. - return f"https://cdn.pixabay.com/photo/2024/01/02/10/33/stream-8482939_1280.jpg" - - async def _arun( - self, - query: str, - run_manager: Optional[AsyncCallbackManagerForToolRun] = None, - ) -> str: - """Use the tool asynchronously.""" - # For this example, we're delegating to the sync implementation. - # If the processing is expensive, you might want to implement a truly - # asynchronous version or remove this method entirely. - return self._run(query, run_manager=run_manager.get_sync() if run_manager else None) - - -# Example usage -if __name__ == "__main__": - # Create a task with initial subtasks - article_task = Task(name="Write Article", - description="Write an article about AI advancements. The final output should strictly include only the title and the content and cover image, without any additional sections or formatting.") - - tasks = [ - article_task - ] - - llm = ChatOllama(model="llama3.1:latest") - tool_llm = OllamaFunctions(model="llama3.1:latest", format="json") - - # Create specialized agents - agents = [ - LLMTaskOperator( - name="research", - role="Online search things", - context="Can search for facts and points on the internet in a variety of ways.", - skills=[ - "Search online", - "Keyword Research", - "Online Research", - "Research", - "Researching", - "Researcher", - ], - tools=[], - llm=llm, - tool_llm=tool_llm - ), - LLMTaskOperator( - name="image_generation", - role="Image Generation", - context="Can generate images from text.", - skills=[ - "Image Generation", - ], - tools=[ - ImageGenerationTool() - ], - llm=llm, - tool_llm=tool_llm - ), - - LLMTaskOperator( - name="writing", - role="Content Strategist & Writer", - context="Deep understanding of various writing styles, content formats, " - "and audience engagement strategies. Knowledgeable about " - "SEO-friendly writing, storytelling techniques, and brand voice " - "development. Familiar with content management systems and digital publishing platforms.", - skills=[ - "Creative Writing", - "Technical Writing", - "Copywriting", - "Content Strategy", - "Storytelling", - "SEO Writing", - "Editing and Proofreading", - "Brand Voice Development", - "Audience Analysis", - "Multimedia Content Creation" - ], - tools=[], - llm=llm - ), - - LLMTaskOperator( - name="seo_optimization", - role="SEO Strategist", - context="Comprehensive understanding of search engine algorithms," - " ranking factors, and SEO best practices. Proficient in technical SEO," - " content optimization, and link building strategies. Familiar with local SEO," - " mobile optimization, and voice search optimization.", - skills=[ - "Keyword Research", - "On-Page SEO", - "Off-Page SEO", - "Technical SEO", - "Content Optimization", - "Link Building", - "Local SEO", - "Mobile SEO", - "Voice Search Optimization", - "SEO Analytics and Reporting" - ], - tools=[], - llm=llm - ), - - LLMTaskOperator( - name="web_publishing", - role="Digital Content Manager", - context="Extensive knowledge of web publishing platforms, " - "content management systems, and digital asset management. " - "Proficient in HTML, CSS, and basic JavaScript. Familiar with web accessibility standards, " - "responsive design principles, and UX/UI best practices.", - skills=[ - "CMS Management", - "HTML/CSS", - "Content Scheduling", - "Digital Asset Management", - "Web Accessibility", - "Responsive Design", - "Version Control", - "A/B Testing", - "Web Analytics", - "User Experience Optimization" - ], - tools=[], - llm=llm - ) - ] - - task_manager = LLMTaskCoordinator(tasks, agents, tool_llm=tool_llm, llm=llm) - tasks = task_manager.do(inputs=b"") - - for t in tasks: - print(t.final_answer) diff --git a/bindings/ceylon/tests/tasks/article-writer-agents-gen.py b/bindings/ceylon/tests/tasks/article-writer-agents-gen.py deleted file mode 100644 index 43c22335..00000000 --- a/bindings/ceylon/tests/tasks/article-writer-agents-gen.py +++ /dev/null @@ -1,118 +0,0 @@ -from langchain_ollama import ChatOllama -from langchain_openai import ChatOpenAI - -from ceylon.llm import LLMTaskOperator, LLMTaskCoordinator -from ceylon.task import Task - -# Example usage -if __name__ == "__main__": - # Create a task with initial subtasks - article_task = Task(name="Write Article", - description="Write an article about AI advancements. The final output should strictly include only the title and the content, without any additional sections or formatting.") - - tasks = [ - article_task - ] - - # llm = ChatOllama(model="mistral-nemo:latest", temperature=0) - # tool_llm = ChatOllama(model="mistral-nemo:latest", format="json", temperature=0) - - llm = ChatOpenAI( - model_name='gpt-4o-mini' - ) - # Create specialized agents - agents = [ - LLMTaskOperator( - name="research", - role="Research Analyst", - context="Extensive knowledge of research methodologies," - " data collection techniques, and analytical tools. " - "Proficient in both qualitative and quantitative research methods. " - "Familiar with academic, market, and industry-specific research practices.", - skills=[ - "Market Research", - "Data Analysis", - "Literature Review", - "Survey Design", - "Interviewing Techniques", - "Statistical Analysis", - "Trend Forecasting", - "Competitive Intelligence", - "Research Report Writing", - "Data Visualization" - ], - llm=llm - ), - - LLMTaskOperator( - name="writing", - role="Content Strategist & Writer", - context="Deep understanding of various writing styles, content formats, " - "and audience engagement strategies. Knowledgeable about " - "SEO-friendly writing, storytelling techniques, and brand voice " - "development. Familiar with content management systems and digital publishing platforms.", - skills=[ - "Creative Writing", - "Technical Writing", - "Copywriting", - "Content Strategy", - "Storytelling", - "SEO Writing", - "Editing and Proofreading", - "Brand Voice Development", - "Audience Analysis", - "Multimedia Content Creation" - ], - llm=llm - ), - - LLMTaskOperator( - name="seo_optimization", - role="SEO Strategist", - context="Comprehensive understanding of search engine algorithms," - " ranking factors, and SEO best practices. Proficient in technical SEO," - " content optimization, and link building strategies. Familiar with local SEO," - " mobile optimization, and voice search optimization.", - skills=[ - "Keyword Research", - "On-Page SEO", - "Off-Page SEO", - "Technical SEO", - "Content Optimization", - "Link Building", - "Local SEO", - "Mobile SEO", - "Voice Search Optimization", - "SEO Analytics and Reporting" - ], - llm=llm - ), - - LLMTaskOperator( - name="web_publishing", - role="Digital Content Manager", - context="Extensive knowledge of web publishing platforms, " - "content management systems, and digital asset management. " - "Proficient in HTML, CSS, and basic JavaScript. Familiar with web accessibility standards, " - "responsive design principles, and UX/UI best practices.", - skills=[ - "CMS Management", - "HTML/CSS", - "Content Scheduling", - "Digital Asset Management", - "Web Accessibility", - "Responsive Design", - "Version Control", - "A/B Testing", - "Web Analytics", - "User Experience Optimization" - ], - llm=llm - ) - ] - - task_manager = LLMTaskCoordinator(tasks, agents, llm=llm) - tasks = task_manager.do(inputs=b"") - - for t in tasks: - print(t.final_answer) diff --git a/bindings/ceylon/tests/tasks/article-writer-agents.py b/bindings/ceylon/tests/tasks/article-writer-agents.py deleted file mode 100644 index 81230010..00000000 --- a/bindings/ceylon/tests/tasks/article-writer-agents.py +++ /dev/null @@ -1,76 +0,0 @@ -from langchain_community.chat_models import ChatOllama -from langchain_openai import ChatOpenAI - -from ceylon.task import Task, SubTask -from ceylon.llm import LLMTaskOperator, LLMTaskCoordinator - -# Example usage -if __name__ == "__main__": - # Create a task with initial subtasks - article_task = Task.create_task("Write Article", "Write an article about AI advancements", - subtasks=[ - SubTask(name="research", description="Conduct research for the article", - required_specialty="Knowledge about research methodologies and tools"), - SubTask(name="writing", description="Write the main content of the article", - depends_on={"research"}, - required_specialty="Knowledge about content writing"), - SubTask(name="seo_optimization", description="Optimize the article for SEO", - depends_on={"writing"}, - required_specialty="Knowledge about SEO strategies and tools"), - SubTask(name="web_publishing", - description="Final article for web publishing, need to ready for publication", - depends_on={"seo_optimization"}, - required_specialty="Knowledge about web publishing tools"), - ]) - - tasks = [ - article_task - ] - - llm = ChatOpenAI( - base_url='http://localhost:11434/v1', - api_key='ollama', # required, but unused - model_name='llama3.1:latest' - ) - - # Create specialized agents - agents = [ - LLMTaskOperator( - name="research", - role="Researcher", - context="Knowledge about research methodologies and tools", - skills=["Market Research", "Data Analysis", "Literature Review"], # Example skills - llm=llm - ), - - LLMTaskOperator( - name="writing", - role="Content Writer", - context="Knowledge about content writing", - skills=["Creative Writing", "Technical Writing", "Copywriting"], # Example skills - llm=llm - ), - - LLMTaskOperator( - name="seo_optimization", - role="SEO Expert", - context="Knowledge about SEO strategies and tools", - skills=["Keyword Research", "On-Page SEO", "Content Optimization"], # Example skills - llm=llm - ), - - LLMTaskOperator( - name="web_publishing", - role="Writer", - context="Knowledge about web publishing tools", - skills=["CMS Management", "HTML/CSS", "Content Scheduling"], # Example skills - llm=llm - ) - ] - - task_manager = LLMTaskCoordinator(tasks, agents, llm=llm, context="You team is working to write an article", - team_goal="Write quickly and accurately") - tasks = task_manager.do(inputs=b"") - - for t in tasks: - print(t.final_answer) diff --git a/bindings/ceylon/tests/tasks/fw_tool.py b/bindings/ceylon/tests/tasks/fw_tool.py deleted file mode 100644 index 97c50dcd..00000000 --- a/bindings/ceylon/tests/tasks/fw_tool.py +++ /dev/null @@ -1,49 +0,0 @@ -from typing import Optional, Type -from pydantic import BaseModel -from langchain.tools.file_management.write import WriteFileTool -import json -from json import JSONDecodeError - - -class FixedWriteFileTool(WriteFileTool): - description = ( - "Write file to disk. " - "Provide the file path and the text content as a JSON-formatted string. " - "Example input: {\"file_path\": \"test.txt\", \"text\": \"This is some test text.\"}" - ) - args_schema: Optional[Type[BaseModel]] = None - - def _run(self, file_path_and_text: str) -> str: - try: - data = json.loads(file_path_and_text) - if "file_path" not in data or "text" not in data: - return "Invalid input: missing 'file_path' or 'text' key." - return super()._run(data["file_path"], data["text"]) - except Exception as e: - print(e) - print("Invalid JSON input.", file_path_and_text) - return "Failed to write file: Invalid JSON input." - return super()._run(data["file_path"], data["text"]) - - @staticmethod - def is_valid_json(input_string): - try: - json.loads(input_string) - return True - except JSONDecodeError: - return False - - # def _run(self, file_path_and_text: str) -> str: - # print() - # print(file_path_and_text) - # file_path_and_text = "{\"" + file_path_and_text + "\"}" - # print() - # print(file_path_and_text) - # file_path_and_text_json = None - # if FixedWriteFileTool.is_valid_json(file_path_and_text): - # file_path_and_text_json = json.loads(file_path_and_text) - # return super()._run(file_path_and_text_json["file_path"], file_path_and_text_json["text"]) - # else: - # return "Failed to write file." - # - # return super().run(file_path_and_text_json["file_path"], file_path_and_text_json["text"]) diff --git a/bindings/ceylon/tests/tasks/llm_software_agency-gorq.py b/bindings/ceylon/tests/tasks/llm_software_agency-gorq.py deleted file mode 100644 index 9869578a..00000000 --- a/bindings/ceylon/tests/tasks/llm_software_agency-gorq.py +++ /dev/null @@ -1,80 +0,0 @@ -import asyncio -from textwrap import dedent - -from langchain_groq import ChatGroq -from langchain_openai import ChatOpenAI - -from ceylon.llm import LLMTaskOperator, LLMTaskCoordinator -from ceylon.task import Task -from ceylon.utils.agent_monitor import AgentMonitor - -# Define the main task -task_management_app = Task( - name="Create Task Management App", - description=dedent(""" - Develop a advanced task management application with features for adding, listing, and completing tasks. - and with priority from list.also need to download list of tasks by date.and need to check finished tasks - no need to use DB. only UI base output is enough. final output must be python script. - """) -) - -tasks = [task_management_app] - -# Initialize language models - -llm = ChatGroq(model_name="mixtral-8x7b-32768") -tool_llm = ChatGroq(model_name="mixtral-8x7b-32768") -code_llm = ChatGroq(model_name="llama-3.1-70b-versatile") - -# Create specialized agents -agents = [ - LLMTaskOperator( - name="backend_developer", - role="Python Backend Developer", - context="Experienced in developing backend systems, API design, and database integration.", - skills=[ - "Python Programming", - ], - tools=[], - llm=code_llm - ), - LLMTaskOperator( - name="frontend_developer", - role="Python Frontend Developer", - context="Proficient in creating user interfaces and handling user interactions in Python applications.", - skills=[ - "UI Design", - "User Experience", - "Python GUI Frameworks like Tkinter", - ], - tools=[], - llm=code_llm - ), - AgentMonitor() -] -# enable_log("INFO") -# Initialize TaskManager -task_manager = LLMTaskCoordinator(tasks, agents, tool_llm=tool_llm, llm=llm, - team_goal=dedent(""" - Develop and deliver straightforward, secure, and efficient Python-based - software solutions that provide clear business value, - achieve 95% client satisfaction, and are completed on time and within budget - """), - context=dedent(""" - Employ agile methodologies to gather and analyze client requirements, design simple yet - robust solutions, implement clean and readable Python code, conduct thorough testing, - and deploy using streamlined CI/CD practices. Prioritize code simplicity, - maintainability, and adherence to Python best practices - throughout the development lifecycle, following the principle that - 'simple is better than complex'. - """), - ) -# task_manager.visualize_team_network(output_file=None) -# Execute tasks -completed_tasks = asyncio.run(task_manager.async_do(inputs=b"")) - -# Print results -for task in completed_tasks: - print(f"Task: {task.name}") - print(f"Result: {task.final_answer}") - print("-" * 50) diff --git a/bindings/ceylon/tests/tasks/llm_software_agency.py b/bindings/ceylon/tests/tasks/llm_software_agency.py deleted file mode 100644 index 3320bdd2..00000000 --- a/bindings/ceylon/tests/tasks/llm_software_agency.py +++ /dev/null @@ -1,158 +0,0 @@ -import asyncio -from pathlib import Path -from textwrap import dedent - -from langchain_community.agent_toolkits import FileManagementToolkit -from langchain_community.agent_toolkits.github.toolkit import GitHubToolkit -from langchain_community.utilities.github import GitHubAPIWrapper -from langchain_openai import ChatOpenAI -from loguru import logger - -from ceylon.ceylon import enable_log -from ceylon.llm import LLMTaskOperator, LLMTaskCoordinator -from ceylon.task import Task -from ceylon.utils.agent_monitor import AgentMonitor -from tasks.fw_tool import FixedWriteFileTool - -enable_log("INFO") -# Define the main task -task_management_app = Task( - name="Create Task Management App", - description=dedent(""" - Need a software to print "Hello Ceylon" in console. - """) -) - -import getpass -import os - -for env_var in [ - "GITHUB_APP_ID", - "GITHUB_APP_PRIVATE_KEY", - "GITHUB_REPOSITORY", -]: - if not os.getenv(env_var): - os.environ[env_var] = getpass.getpass() - -tasks = [task_management_app] - -# Initialize language models - -llm = ChatOpenAI(model="gpt-4o-mini") -tool_llm = ChatOpenAI(model="gpt-4o-mini") -code_llm = ChatOpenAI(model="gpt-4o-mini") - -# github = GitHubAPIWrapper() -# toolkit = GitHubToolkit.from_github_api_wrapper(github) - - -working_directory = Path("software") -logger.info(working_directory.absolute()) -root_dir = f"{working_directory.absolute()}" -toolkit = FileManagementToolkit( - root_dir=root_dir, - selected_tools=["read_file"], -) # If you don't provide a root_dir, operations will default to the current working directory -logger.info(toolkit.get_tools()) - -# Create specialized agents -agents = [ - LLMTaskOperator( - name="backend_developer", - role="Python Backend Developer", - context="Specializes in server-side logic, API development, database design, and system architecture. Focuses on efficiency, scalability, and security.", - skills=[ - "Python Programming", - "RESTful API Design", - "Database Management (SQL and NoSQL)", - "Server Architecture", - "Authentication and Authorization", - "Asynchronous Programming", - "Microservices Architecture", - ], - tools=[], - llm=code_llm - ), - LLMTaskOperator( - name="frontend_developer", - role="Python Frontend Developer", - context="Expertise in creating intuitive and responsive user interfaces for Python applications. Focuses on user experience, accessibility, and cross-platform compatibility.", - skills=[ - "UI/UX Design Principles", - "Python GUI Frameworks (Tkinter, PyQt, wxPython)", - "Event-driven Programming", - "Responsive Design", - "User Input Validation", - "Data Visualization", - "Accessibility Standards", - ], - tools=[], - llm=code_llm - ), - LLMTaskOperator( - name="qa_engineer", - role="QA Engineer", - context="Ensures software quality through comprehensive testing strategies. Focuses on identifying bugs, improving user experience, and maintaining code integrity.", - skills=[ - "Test Planning and Strategy", - "Unit Testing (pytest, unittest)", - "Integration Testing", - "End-to-End Testing (Selenium, Behave)", - "Performance Testing (Locust)", - "Security Testing", - "API Testing (Postman, requests)", - "Continuous Integration/Continuous Deployment (CI/CD)", - "Bug Tracking and Reporting", - ], - tools=[], - llm=code_llm, - verbose=True - ), - LLMTaskOperator( - name="source_code_writer", - role="Source Code Manager", - context="Responsible for creating, organizing, and managing source code files within the project structure. Ensures code consistency and proper file management.", - skills=[ - "File System Operations", - "Source Code Organization", - "Version Control Integration", - "Code Template Generation", - "Project Structure Management", - "File Naming Conventions", - "Code Documentation", - ], - tools=[ - *toolkit.get_tools(), - FixedWriteFileTool( - root_dir=root_dir, ) - ], - llm=code_llm, - verbose=True - ), - AgentMonitor() -] -# Initialize TaskManager -task_manager = LLMTaskCoordinator(tasks, agents, tool_llm=tool_llm, llm=llm, - team_goal=dedent(""" - Develop and deliver straightforward, secure, and efficient Python-based - software solutions that provide clear business value, - achieve 95% client satisfaction, and are completed on time and within budget - """), - context=dedent(""" - Employ agile methodologies to gather and analyze client requirements, design simple yet - robust solutions, implement clean and readable Python code, conduct thorough testing, - and deploy using streamlined CI/CD practices. Prioritize code simplicity, - maintainability, and adherence to Python best practices - throughout the development lifecycle, following the principle that - 'simple is better than complex'. - """), - ) -# task_manager.visualize_team_network(output_file=None) -# Execute tasks -completed_tasks = asyncio.run(task_manager.async_do(inputs=b"")) - -# Print results -for task in completed_tasks: - print(f"Task: {task.name}") - print(f"Result: {task.final_answer}") - print("-" * 50) diff --git a/bindings/ceylon/tests/tasks/manage_tasks-agents.py b/bindings/ceylon/tests/tasks/manage_tasks-agents.py deleted file mode 100644 index a109fffc..00000000 --- a/bindings/ceylon/tests/tasks/manage_tasks-agents.py +++ /dev/null @@ -1,103 +0,0 @@ -from langchain_community.chat_models import ChatOllama - -from ceylon.llm import LLMTaskCoordinator, LLMTaskOperator -from ceylon.task import Task, SubTask -from ceylon.task.task_operation import TaskDeliverable - -# Example usage -if __name__ == "__main__": - # Create a task with initial subtasks - web_app = Task.create_task("Build Web App", "Create a simple web application", - subtasks=[ - SubTask(name="setup", description="Set up the development environment", - required_specialty="Knowledge about deployment and development tools"), - SubTask(name="database", description="Set up the database", - required_specialty="Knowledge about database management tools"), - SubTask(name="testing", description="Perform unit and integration tests", - depends_on={"backend", "frontend"}, - required_specialty="Knowledge about testing tools"), - SubTask(name="frontend", description="Develop the frontend UI", - depends_on={"setup", "backend"}, - required_specialty="Knowledge about frontend tools"), - SubTask(name="backend", description="Develop the backend API", - depends_on={"setup", "database"}, - required_specialty="Knowledge about backend tools"), - SubTask(name="deployment", description="Deploy the application", - depends_on={"testing", "qa"}, - required_specialty="Knowledge about deployment tools and CI tools"), - SubTask(name="delivery", description="Deploy the application", - depends_on={"deployment"}, - required_specialty="Knowledge about delivery tools"), - SubTask(name="qa", description="Perform quality assurance", - depends_on={"testing"}, - required_specialty="Knowledge about testing tools") - - ]) - web_app.task_deliverable = TaskDeliverable.default(web_app.description) - tasks = [ - web_app - ] - - llm = ChatOllama(model="llama3.1:latest", temperature=0) - # Create specialized agents - agents = [ - LLMTaskOperator( - name="backend", - role="Backend Developer", - context="Knowledge about backend tools", - skills=["Python", "Java", "Node.js"], # Example skills - llm=llm - ), - - LLMTaskOperator( - name="setup", - role="Setup Manager", - context="Knowledge about deployment and development tools", - skills=["CI/CD", "Docker", "Kubernetes"], # Example skills - llm=llm - ), - - - LLMTaskOperator( - name="frontend", - role="Frontend Developer", - context="Knowledge about frontend tools", - skills=["HTML", "CSS", "JavaScript", "React"], # Example skills - llm=llm - ), - - LLMTaskOperator( - name="database", - role="Database Administrator", - context="Knowledge about database management tools", - skills=["SQL", "NoSQL", "Database Design"], # Example skills - llm=llm - ), - # - LLMTaskOperator( - name="deployment", - role="Deployment Manager", - context="Knowledge about deployment tools and CI tools", - skills=["CI/CD", "Docker", "Kubernetes"], # Example skills - llm=llm - ), - # - # LLMTaskOperator( - # name="qa", - # role="Quality Assurance Engineer", - # context="Knowledge about testing tools", - # skills=["Automated Testing", "Manual Testing", "Test Case Design"], # Example skills - # llm=llm - # ), - # - # LLMTaskOperator( - # name="delivery", - # role="Delivery Manager", - # context="Knowledge about delivery tools", - # skills=["Release Management", "Continuous Delivery"], # Example skills - # llm=llm - # ) - - ] - task_manager = LLMTaskCoordinator(tasks, agents, llm=llm) - task_manager.do() diff --git a/bindings/ceylon/tests/tasks/manage_tasks.py b/bindings/ceylon/tests/tasks/manage_tasks.py deleted file mode 100644 index 68edd3a8..00000000 --- a/bindings/ceylon/tests/tasks/manage_tasks.py +++ /dev/null @@ -1,186 +0,0 @@ -from typing import Dict, List, Optional, Set, Tuple -from uuid import uuid4 - -import networkx as nx -from pydantic import BaseModel, Field - - -class SubTask(BaseModel): - id: str = Field(default_factory=lambda: str(uuid4()), alias='_id') - name: str - description: str - depends_on: Set[str] = Field(default_factory=set) - completed: bool = False - - def complete(self): - self.completed = True - - def __str__(self): - status = "Completed" if self.completed else "Pending" - return f"SubTask: {self.name} (ID: {self.id}) - {status} - Dependencies: {self.depends_on}" - - -class Task(BaseModel): - id: str = Field(default_factory=lambda: str(uuid4()), alias='_id') - name: str - description: str - subtasks: Dict[str, SubTask] = Field(default_factory=dict) - - execution_order: List[str] = Field(default_factory=list) - - def add_subtask(self, subtask: SubTask): - if subtask.name in self.subtasks: - raise ValueError(f"Subtask with id {subtask.name} already exists") - - self.subtasks[subtask.name] = subtask - self._validate_dependencies() - self.execution_order = self.get_execution_order() - - def _validate_dependencies(self): - graph = self._create_dependency_graph() - if not nx.is_directed_acyclic_graph(graph): - raise ValueError("The dependencies create a cycle") - - def _create_dependency_graph(self) -> nx.DiGraph: - graph = nx.DiGraph() - for subtask in self.subtasks.values(): - graph.add_node(subtask.name) - return graph - - def validate_sub_tasks(self) -> bool: - subtask_names = set(self.subtasks.keys()) - - # Check if all dependencies are present - for subtask in self.subtasks.values(): - if not subtask.depends_on.issubset(subtask_names): - missing_deps = subtask.depends_on - subtask_names - print(f"Subtask '{subtask.name}' has missing dependencies: {missing_deps}") - return False - - # Check for circular dependencies - try: - self._validate_dependencies() - except ValueError as e: - print(f"Circular dependency detected: {str(e)}") - return False - - def get_execution_order(self) -> List[str]: - graph = self._create_dependency_graph() - return list(nx.topological_sort(graph)) - - def get_next_subtask(self) -> Optional[Tuple[str, SubTask]]: - for subtask_name in self.execution_order: - subtask = self.subtasks[subtask_name] - if all(self.subtasks[dep].completed for dep in subtask.depends_on): - return (subtask_name, subtask) - return None - - def update_subtask_status(self, subtask_name: str, result: bool): - if subtask_name not in self.subtasks: - raise ValueError(f"Subtask {subtask_name} not found") - - subtask = self.subtasks[subtask_name] - if result: - subtask.complete() - - if subtask_name in self.execution_order: - self.execution_order.remove(subtask_name) - - def is_completed(self) -> bool: - return all(subtask.completed for subtask in self.subtasks.values()) - - def __str__(self): - return f"Task: {self.name}\nSubtasks:\n" + "\n".join(str(st) for st in self.subtasks.values()) - - -class TaskManager(BaseModel): - tasks: Dict[str, Task] = Field(default_factory=dict) - - def create_task(self, name: str, description: str, subtasks: List[SubTask] = None) -> Task: - task = Task(name=name, description=description) - if subtasks: - for subtask in subtasks: - task.add_subtask(subtask) - self.tasks[task.id] = task - return task - - def get_task(self, task_id: str) -> Optional[Task]: - return self.tasks.get(task_id) - - def list_tasks(self): - for task in self.tasks.values(): - print(task) - print() - - -def execute_task(task: Task) -> None: - while True: - # Get the next subtask - next_subtask: Optional[tuple[str, SubTask]] = task.get_next_subtask() - - # If there are no more subtasks, break the loop - if next_subtask is None: - break - - subtask_name, subtask = next_subtask - print(f"Executing: {subtask}") - - # Here you would actually execute the subtask - # For this example, we'll simulate execution with a simple print statement - print(f"Simulating execution of {subtask_name}") - - # Simulate a result (in a real scenario, this would be the outcome of the subtask execution) - result = True - - # Update the subtask status - task.update_subtask_status(subtask_name, result) - - # Check if the entire task is completed - if task.is_completed(): - print("All subtasks completed successfully!") - break - - # Final check to see if all subtasks were completed - if task.is_completed(): - print("Task execution completed successfully!") - else: - print("Task execution incomplete. Some subtasks may have failed.") - - -# Example usage -if __name__ == "__main__": - manager = TaskManager() - # Create a task with initial subtasks - web_app = manager.create_task("Build Web App", "Create a simple web application", - subtasks=[ - SubTask(name="setup", description="Set up the development environment"), - SubTask(name="database", description="Set up the database"), - SubTask(name="testing", description="Perform unit and integration tests", - depends_on={"backend", "frontend"}), - SubTask(name="frontend", description="Develop the frontend UI", - depends_on={"setup", "backend"}), - SubTask(name="backend", description="Develop the backend API", - depends_on={"setup", "database"}), - SubTask(name="deployment", description="Deploy the application", - depends_on={"testing", "qa"}), - SubTask(name="delivery", description="Deploy the application", - depends_on={"deployment"}) - ]) - - # Execute the task - print("Execution order:", [web_app.subtasks[task_id].name for task_id in web_app.get_execution_order()]) - - if web_app.validate_sub_tasks(): - print("Subtasks are valid") - - print("\nExecuting task:") - execute_task(task=web_app) - - print("\nFinal task status:") - print(web_app) - else: - print("Subtasks are invalid") - - # Serialization example - print("\nSerialized Task:") - print(web_app.model_dump_json(indent=2)) diff --git a/bindings/ceylon/tests/tasks/sample_game.py b/bindings/ceylon/tests/tasks/sample_game.py deleted file mode 100644 index 31fa1412..00000000 --- a/bindings/ceylon/tests/tasks/sample_game.py +++ /dev/null @@ -1,198 +0,0 @@ -import tkinter as tk -from tkinter import messagebox, filedialog -from datetime import datetime -from dataclasses import dataclass, field -import csv - - -@dataclass -class Task: - description: str - due_date: datetime.date - priority: str - completed: bool = field(default=False) - - -class TaskManager: - def __init__(self): - self.tasks = [] - - def add_task(self, description, due_date, priority): - if priority not in ['High', 'Medium', 'Low']: - raise ValueError("Priority must be 'High', 'Medium', or 'Low'") - task = Task(description, due_date, priority) - self.tasks.append(task) - - def mark_task_completed(self, task_index): - if 0 <= task_index < len(self.tasks): - self.tasks[task_index].completed = True - else: - raise IndexError("Task index out of range") - - def get_pending_tasks(self): - return [task for task in self.tasks if not task.completed] - - def get_finished_tasks(self): - return [task for task in self.tasks if task.completed] - - def edit_task(self, task_index, new_description, new_due_date, new_priority): - if 0 <= task_index < len(self.tasks): - task = self.tasks[task_index] - task.description = new_description - task.due_date = new_due_date - task.priority = new_priority - else: - raise IndexError("Task index out of range") - - def delete_task(self, task_index): - if 0 <= task_index < len(self.tasks): - del self.tasks[task_index] - else: - raise IndexError("Task index out of range") - - def get_tasks_sorted_by_date(self): - return sorted(self.tasks, key=lambda task: task.due_date) - - def export_tasks_to_file(self, filename): - sorted_tasks = self.get_tasks_sorted_by_date() - try: - with open(filename, 'w', newline='') as file: - writer = csv.writer(file) - writer.writerow(["Description", "Due Date", "Priority", "Completed"]) - for task in sorted_tasks: - writer.writerow([task.description, task.due_date, task.priority, task.completed]) - return True - except Exception as e: - print(f"An error occurred while writing to file: {e}") - return False - - -class TaskApp: - def __init__(self, root): - self.root = root - self.root.title("Task Manager") - - self.task_manager = TaskManager() - - # Description - tk.Label(root, text="Description").grid(row=0, column=0) - self.description_entry = tk.Entry(root) - self.description_entry.grid(row=0, column=1) - - # Due Date - tk.Label(root, text="Due Date (YYYY-MM-DD)").grid(row=1, column=0) - self.due_date_entry = tk.Entry(root) - self.due_date_entry.grid(row=1, column=1) - - # Priority - tk.Label(root, text="Priority").grid(row=2, column=0) - self.priority_var = tk.StringVar(value="Medium") - tk.OptionMenu(root, self.priority_var, "High", "Medium", "Low").grid(row=2, column=1) - - # Add Task Button - tk.Button(root, text="Add Task", command=self.add_task).grid(row=3, column=1) - - # Download Task List Button - tk.Button(root, text="Download Task List", command=self.download_task_list).grid(row=3, column=2) - - # Task List - self.task_list_frame = tk.Frame(root) - self.task_list_frame.grid(row=4, column=0, columnspan=3) - self.update_task_list() - - def add_task(self): - description = self.description_entry.get() - due_date_str = self.due_date_entry.get() - priority = self.priority_var.get() - - try: - due_date = datetime.strptime(due_date_str, '%Y-%m-%d').date() - self.task_manager.add_task(description, due_date, priority) - messagebox.showinfo("Success", "Task added successfully!") - self.description_entry.delete(0, tk.END) - self.due_date_entry.delete(0, tk.END) - self.priority_var.set("Medium") - self.update_task_list() - except ValueError as e: - messagebox.showerror("Error", str(e)) - - def update_task_list(self): - for widget in self.task_list_frame.winfo_children(): - widget.destroy() - - tk.Label(self.task_list_frame, text="Pending Tasks").grid(row=0, column=0) - tk.Label(self.task_list_frame, text="Finished Tasks").grid(row=0, column=1) - - pending_tasks = self.task_manager.get_pending_tasks() - finished_tasks = self.task_manager.get_finished_tasks() - - for idx, task in enumerate(pending_tasks): - tk.Label(self.task_list_frame, text=f"{task.description} (Due: {task.due_date}, Priority: {task.priority})").grid(row=idx + 1, column=0) - tk.Button(self.task_list_frame, text="Mark as Done", command=lambda idx=idx: self.mark_task_done(idx)).grid(row=idx + 1, column=1) - tk.Button(self.task_list_frame, text="Edit", command=lambda idx=idx: self.edit_task(idx)).grid(row=idx + 1, column=2) - tk.Button(self.task_list_frame, text="Delete", command=lambda idx=idx: self.delete_task(idx)).grid(row=idx + 1, column=3) - - for idx, task in enumerate(finished_tasks): - tk.Label(self.task_list_frame, text=f"{task.description} (Due: {task.due_date}, Priority: {task.priority})").grid(row=len(pending_tasks) + idx + 1, column=1) - - def mark_task_done(self, task_index): - try: - self.task_manager.mark_task_completed(task_index) - self.update_task_list() - except IndexError as e: - messagebox.showerror("Error", str(e)) - - def edit_task(self, task_index): - try: - task = self.task_manager.tasks[task_index] - self.description_entry.delete(0, tk.END) - self.description_entry.insert(0, task.description) - self.due_date_entry.delete(0, tk.END) - self.due_date_entry.insert(0, task.due_date.strftime('%Y-%m-%d')) - self.priority_var.set(task.priority) - - def save_changes(): - new_description = self.description_entry.get() - new_due_date_str = self.due_date_entry.get() - new_priority = self.priority_var.get() - try: - new_due_date = datetime.strptime(new_due_date_str, '%Y-%m-%d').date() - self.task_manager.edit_task(task_index, new_description, new_due_date, new_priority) - self.update_task_list() - messagebox.showinfo("Success", "Task updated successfully!") - self.description_entry.delete(0, tk.END) - self.due_date_entry.delete(0, tk.END) - self.priority_var.set("Medium") - save_button.destroy() - except ValueError as e: - messagebox.showerror("Error", str(e)) - - save_button = tk.Button(self.root, text="Save Changes", command=save_changes) - save_button.grid(row=3, column=2) - - except IndexError as e: - messagebox.showerror("Error", str(e)) - - def delete_task(self, task_index): - try: - self.task_manager.delete_task(task_index) - self.update_task_list() - messagebox.showinfo("Success", "Task deleted successfully!") - except IndexError as e: - messagebox.showerror("Error", str(e)) - - def download_task_list(self): - filename = filedialog.asksaveasfilename(defaultextension=".csv", filetypes=[("CSV files", "*.csv")]) - if filename: - success = self.task_manager.export_tasks_to_file(filename) - if success: - messagebox.showinfo("Success", "Task list downloaded successfully!") - else: - messagebox.showerror("Error", "Failed to download task list.") - - -if __name__ == "__main__": - root = tk.Tk() - app = TaskApp(root) - root.mainloop() - diff --git a/bindings/ceylon/tests/tasks/task_agent.py b/bindings/ceylon/tests/tasks/task_agent.py deleted file mode 100644 index 2f304a3d..00000000 --- a/bindings/ceylon/tests/tasks/task_agent.py +++ /dev/null @@ -1,173 +0,0 @@ -from typing import Dict, List, Set -from uuid import uuid4 - -import networkx as nx -from pydantic import BaseModel, Field - -from ceylon import Agent, CoreAdmin, on_message - - -# Data Models -class SubTask(BaseModel): - id: str - name: str - description: str - depends_on: Set[str] = Field(default_factory=set) - completed: bool = False - - def complete(self): - self.completed = True - - def __str__(self): - status = "Completed" if self.completed else "Pending" - return f"SubTask: {self.name} (ID: {self.id}) - {status}" - - -class Task(BaseModel): - id: str = Field(default_factory=lambda: str(uuid4()), alias='_id') - name: str - description: str - subtasks: Dict[str, SubTask] = Field(default_factory=dict) - - def add_subtask(self, subtask: SubTask): - if subtask.id in self.subtasks: - raise ValueError(f"Subtask with id {subtask.id} already exists") - self.subtasks[subtask.id] = subtask - self._validate_dependencies() - - def _validate_dependencies(self): - graph = self._create_dependency_graph() - if not nx.is_directed_acyclic_graph(graph): - raise ValueError("The dependencies create a cycle") - - def _create_dependency_graph(self) -> nx.DiGraph: - graph = nx.DiGraph() - for subtask in self.subtasks.values(): - graph.add_node(subtask.id) - for dependency_id in subtask.depends_on: - if dependency_id not in self.subtasks: - raise ValueError(f"Dependency {dependency_id} does not exist") - graph.add_edge(dependency_id, subtask.id) - return graph - - def get_execution_order(self) -> List[str]: - graph = self._create_dependency_graph() - return list(nx.topological_sort(graph)) - - def __str__(self): - return f"Task: {self.name}\nSubtasks:\n" + "\n".join(str(st) for st in self.subtasks.values()) - - -# Messages -class TaskAssignment(BaseModel): - task_id: str - subtask_id: str - - -class SubTaskCompletion(BaseModel): - task_id: str - subtask_id: str - - -# Admin Agent -class TaskManagerAdmin(CoreAdmin): - tasks: Dict[str, Task] = {} - in_progress: Dict[str, Set[str]] = {} - - def __init__(self): - super().__init__(name="task_manager", port=8000) - - def create_task(self, name: str, description: str, subtasks: List[SubTask] = None) -> Task: - task = Task(name=name, description=description) - if subtasks: - for subtask in subtasks: - task.add_subtask(subtask) - print(f"Created task: {task}") - self.tasks[task.id] = task - self.in_progress[task.id] = set() - return task - - async def execute_task(self, task_id: str): - task = self.tasks.get(task_id) - if not task: - print(f"Task with id {task_id} not found") - return - - execution_order = task.get_execution_order() - for subtask_id in execution_order: - subtask = task.subtasks[subtask_id] - if not subtask.completed and subtask_id not in self.in_progress[task_id]: - self.in_progress[task_id].add(subtask_id) - await self.broadcast_data(TaskAssignment(task_id=task_id, subtask_id=subtask_id)) - - @on_message(type=SubTaskCompletion) - async def on_subtask_completion(self, data: SubTaskCompletion): - task = self.tasks.get(data.task_id) - if not task: - print(f"Task with id {data.task_id} not found") - return - - subtask = task.subtasks.get(data.subtask_id) - if not subtask: - print(f"Subtask with id {data.subtask_id} not found in task {data.task_id}") - return - - subtask.complete() - self.in_progress[data.task_id].remove(data.subtask_id) - print(f"Subtask {subtask.name} completed") - - # Check if all subtasks are completed - if all(st.completed for st in task.subtasks.values()): - print(f"Task {task.name} completed") - else: - # Continue executing remaining subtasks - await self.execute_task(data.task_id) - - -# Worker Agent -class WorkerAgent(Agent): - def __init__(self, name: str): - super().__init__(name=name, workspace_id="task_manager", admin_peer="TaskManagerAdmin", admin_port=8000) - - @on_message(type=TaskAssignment) - async def on_task_assignment(self, data: TaskAssignment): - print(f"{self.details().name} received subtask assignment: {data.subtask_id}") - # Simulate work by waiting for a short time - await asyncio.sleep(2) - print(f"{self.details().name} completed subtask: {data.subtask_id}") - await self.broadcast_data(SubTaskCompletion(task_id=data.task_id, subtask_id=data.subtask_id)) - - -# Example usage -async def main(): - admin = TaskManagerAdmin() - workers = [WorkerAgent(f"Worker-{i}") for i in range(3)] - - # Create subtasks - subtasks = [ - SubTask(id="setup", name="Setup", description="Set up the development environment"), - SubTask(id="database", name="Database", description="Set up the database"), - SubTask(id="backend", name="Backend", description="Develop the backend API", depends_on={"setup", "database"}), - SubTask(id="frontend", name="Frontend", description="Develop the frontend UI", depends_on={"setup"}), - SubTask(id="testing", name="Testing", description="Perform unit and integration tests", - depends_on={"backend", "frontend"}), - SubTask(id="deployment", name="Deployment", description="Deploy the application", depends_on={"testing"}) - ] - - # Create a task with initial subtasks - web_app = admin.create_task("Build Web App", "Create a simple web application", subtasks=subtasks) - - print("Execution order:", [web_app.subtasks[task_id].name for task_id in web_app.get_execution_order()]) - print("\nStarting task execution:") - - await admin.arun_admin( - inputs=pickle.dumps({"task_id": web_app.id}), - workers=workers - ) - - -if __name__ == "__main__": - import asyncio - import pickle - - asyncio.run(main()) diff --git a/bindings/ceylon/tests/tasks/task_with_human_inputs.py b/bindings/ceylon/tests/tasks/task_with_human_inputs.py deleted file mode 100644 index 59948aa5..00000000 --- a/bindings/ceylon/tests/tasks/task_with_human_inputs.py +++ /dev/null @@ -1,43 +0,0 @@ -from typing import Any - -from ceylon.task import SubTask, Task -from ceylon.task.task_coordinator import TaskCoordinator -from ceylon.task.task_human_intractive_operator import TaskOperatorWithHumanInteractive -from ceylon.task.task_operator import TaskOperator - - -class TaskOperatorOne(TaskOperator): - async def get_result(self, task) -> Any: - return "Hello, World! From Task Operator One" - - -class TaskOperatorTwo(TaskOperator): - async def get_result(self, task) -> Any: - return "Hello, World! From Task Operator Two" - - -admin = TaskCoordinator() -admin.add_agents([ - TaskOperatorOne(name="TaskOperatorOne", role="TaskOperator One"), - TaskOperatorTwo(name="TaskOperatorTwo", role="TaskOperator Two"), - TaskOperatorWithHumanInteractive(name="TaskOperatorWithHumanInteractive", role="TaskOperator With Human Interactive") -]) - -# Create subtasks -subtasks = [ - SubTask(name="setup", description="Set up the development environment", executor="TaskOperatorOne"), - SubTask(name="database", description="Set up the database", executor="TaskOperatorTwo"), - SubTask(name="backend", description="Develop the backend API", depends_on={"setup", "database"}, - executor="TaskOperatorOne"), - SubTask(name="frontend", description="Develop the frontend UI", depends_on={"setup"}, - executor="TaskOperatorTwo"), - SubTask(name="testing", description="Perform unit and integration tests", - depends_on={"backend", "frontend"}, executor="TaskOperatorTwo"), - SubTask(name="title", description="Deploy the application", depends_on={"testing"}, - executor="TaskOperatorWithHumanInteractive"), - SubTask(name="deployment", description="Deploy the application", depends_on={"testing"}, - executor="TaskOperatorOne") -] -task = Task.create_task(name="Build Web App", description="Create a simple web application", subtasks=subtasks) -admin.add_tasks([task]) -admin.do() diff --git a/bindings/ceylon/tests/tasks/task_with_human_inputs_llma.py b/bindings/ceylon/tests/tasks/task_with_human_inputs_llma.py deleted file mode 100644 index 08e6cae6..00000000 --- a/bindings/ceylon/tests/tasks/task_with_human_inputs_llma.py +++ /dev/null @@ -1,60 +0,0 @@ -from langchain_openai import ChatOpenAI - -from ceylon.llm import LLMTaskOperator, LLMTaskCoordinator -from ceylon.task import Task, SubTask -from ceylon.task.task_human_intractive_operator import TaskOperatorWithHumanInteractive - -llm = ChatOpenAI( - base_url='http://localhost:11434/v1', - api_key='ollama', # required, but unused - model_name='llama3.1:latest' -) - -admin = LLMTaskCoordinator( - llm=llm -) -admin.add_agents([ - LLMTaskOperator( - name="research", - role="Researcher", - context="Knowledge about research methodologies and tools", - skills=["Market Research", "Data Analysis", "Literature Review"], # Example skills - llm=llm - ), - - LLMTaskOperator( - name="writing", - role="Content Writer", - context="Knowledge about content writing", - skills=["Creative Writing", "Technical Writing", "Copywriting"], # Example skills - llm=llm - ), - TaskOperatorWithHumanInteractive(name="get_user_inputs", role="Get Human Inputs from User") -]) - -# Create subtasks -subtasks = [ - SubTask(name="research", description="Conduct research on SaaS concepts and examples", executor="research"), - SubTask(name="outline", description="Create an outline for the article", depends_on={"research"}, - executor="writing"), - SubTask(name="draft", description="Write the first draft of the article", depends_on={"outline"}, - executor="writing"), - SubTask(name="review", description="Internal review and editing of the draft", depends_on={"draft"}, - executor="writing"), - SubTask(name="feedback", description="Gather user feedback on the article", depends_on={"review"}, - executor="get_user_inputs"), - SubTask(name="revise", description="Revise the article based on user feedback", depends_on={"feedback"}, - executor="writing"), - SubTask(name="finalize", description="Finalize and proofread the article", depends_on={"revise"}, - executor="writing") -] - -task = Task.create_task(name="Create SaaS Article", - description="Create a simple article about SaaS, get user feedback before final", - subtasks=subtasks) - -admin.add_tasks([task]) -results = admin.do() - -for task in results: - print(task.final_answer) diff --git a/bindings/ceylon/tests/test_agent.py b/bindings/ceylon/tests/test_agent.py deleted file mode 100644 index 7f10d6e9..00000000 --- a/bindings/ceylon/tests/test_agent.py +++ /dev/null @@ -1,24 +0,0 @@ -from unittest import TestCase - -from ceylon.llm.types.agent import AgentDefinition -from ceylon.llm.prompt import PromptMessage - - -class TestAgentDefinition(TestCase): - def test_intro(self): - definition = AgentDefinition( - name="test", - role="test-role", - objective="test-objective", - context="test-context", - ) - self.assertEqual(definition.intro, - {"name": "test", "role": "test-role", "objective": "test-objective", - "context": "test-context"}) - prompt_msg = PromptMessage(path="prompts.agent") - self.assertEqual(definition.prompt, prompt_msg.build(**{ - "name": "test", - "role": "test-role", - "objective": "test-objective", - "context": "test-context", - })) diff --git a/bindings/ceylon/tests/test_agents.py b/bindings/ceylon/tests/test_agents.py deleted file mode 100644 index 60eb3ffb..00000000 --- a/bindings/ceylon/tests/test_agents.py +++ /dev/null @@ -1,110 +0,0 @@ -import asyncio -import pickle - -from pydantic.dataclasses import dataclass - -from ceylon import AgentRunner -from ceylon.ceylon import AgentCore, MessageHandler, Processor, AgentDefinition -from ceylon.runner import RunnerInput - - -@dataclass -class GameBoard: - grid: list - - def __str__(self): - return str(self.grid) - - -def find_position(grid, item): - for row_idx, row in enumerate(grid): - for col_idx, cell in enumerate(row): - if cell == item: - return row_idx, col_idx - return None - - -class SimpleAgent(AgentCore, MessageHandler, Processor): - - def __init__(self, name): - super().__init__(definition=AgentDefinition( - name=name, - position="player", - instructions=[], - responsibilities=[] - ), on_message=self, processor=self) - self.goal = None - self.agent_position = None - - async def run(self, inputs: "bytes"): - agent_def = await self.definition() - input_request: RunnerInput = pickle.loads(inputs) - game_board: GameBoard = input_request.request - - if not self.goal or not self.agent_position: - self.goal = find_position(game_board.grid, 'G') - self.agent_position = find_position(game_board.grid, 'A') - - await self.move(game_board) - print(agent_def.name, game_board) - - await self.broadcast(pickle.dumps(game_board)) - - async def on_message(self, agent_id: "str", data: "bytes", time: "int"): - game_board: GameBoard = pickle.loads(data) - print("Game board", game_board) - - await self.move(game_board) - await self.broadcast(pickle.dumps(game_board)) - - async def move(self, game_board): - row, col = self.agent_position - goal_row, goal_col = self.goal - - # Determine the direction to move - if row < goal_row and game_board.grid[row + 1][col] != 1: - new_position = (row + 1, col) - elif row > goal_row and game_board.grid[row - 1][col] != 1: - new_position = (row - 1, col) - elif col < goal_col and game_board.grid[row][col + 1] != 1: - new_position = (row, col + 1) - elif col > goal_col and game_board.grid[row][col - 1] != 1: - new_position = (row, col - 1) - else: - new_position = self.agent_position # No move possible - - # Update the agent's position - await self.update_position(game_board, new_position) - - async def update_position(self, game_board, new_position): - old_row, old_col = self.agent_position - new_row, new_col = new_position - - game_board.grid[old_row][old_col] = 0 - game_board.grid[new_row][new_col] = 'A' - self.agent_position = new_position - - print(f"Agent {(await self.definition()).name} moved from ({old_row}, {old_col}) to ({new_row}, {new_col})") - - -async def main(): - worker = AgentRunner(workspace_name="ceylon-ai") - - worker.register_agent(SimpleAgent("agent_1")) - worker.register_agent(SimpleAgent("agent_2")) - - game_board = GameBoard( - grid=[ - [0, 0, 0, 0, 0], - [0, 1, 1, 1, 0], - [0, 0, 0, 1, 0], - [0, 1, 0, 0, 0], - ['A', 0, 0, 1, 'G'] - ] - ) - print(game_board) - await worker.run(game_board) - - -if __name__ == '__main__': - asyncio.run(main()) diff --git a/bindings/ceylon/tests/test_prompt.py b/bindings/ceylon/tests/test_prompt.py deleted file mode 100644 index 47720887..00000000 --- a/bindings/ceylon/tests/test_prompt.py +++ /dev/null @@ -1,10 +0,0 @@ -from unittest import TestCase - -from ceylon.llm.prompt import PromptMessage - - -class TestPromptMessage(TestCase): - def test_build(self): - prompt = PromptMessage(path="prompts.agent") - prompt_txt = prompt.build(name="test", role="test-role", objective="test-objective", context="test-context") - print(prompt_txt) diff --git a/bindings/ceylon/tests/test_worker/__init__.py b/bindings/ceylon/tests/test_worker/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/tests/test_worker/auction.py b/bindings/ceylon/tests/test_worker/auction.py deleted file mode 100644 index 4086911e..00000000 --- a/bindings/ceylon/tests/test_worker/auction.py +++ /dev/null @@ -1,117 +0,0 @@ -import pickle -import random -from typing import List - -from pydantic.dataclasses import dataclass - -from ceylon import Agent, on_message -from ceylon import CoreAdmin - -admin_port = 8000 -admin_peer = "Auctioneer" -workspace_id = "single_item_auction" - - -@dataclass(repr=True) -class Item: - name: str - starting_price: float - - -@dataclass(repr=True) -class Bid: - bidder: str - amount: float - - -@dataclass(repr=True) -class AuctionStart: - item: Item - - -@dataclass(repr=True) -class AuctionResult: - winner: str - winning_bid: float - - -@dataclass(repr=True) -class AuctionEnd: - pass - - -class Bidder(Agent): - name: str - budget: float - - def __init__(self, name: str, budget: float): - self.name = name - self.budget = budget - super().__init__(name=name, workspace_id=workspace_id, admin_peer=admin_peer, admin_port=admin_port, - role="bidder") - - @on_message(type=AuctionStart) - async def on_auction_start(self, data: AuctionStart): - if self.budget > data.item.starting_price: - random_i = random.randint(100, 1000) - bid_amount = min(self.budget, data.item.starting_price * random_i / 100) # Simple bidding strategy - await self.broadcast_data(Bid(bidder=self.name, amount=bid_amount)) - - @on_message(type=Bid) - async def on_auction_result(self, data: AuctionResult): - self.budget -= data.winning_bid - print(f"{self.name} won the auction for ${data.winning_bid:.2f}") - - -class Auctioneer(CoreAdmin): - item: Item - bids: List[Bid] = [] - expected_bidders: int - connected_bidders: int = 0 - - def __init__(self, item: Item, expected_bidders: int): - self.item = item - self.expected_bidders = expected_bidders - super().__init__(name=workspace_id, port=admin_port) - - async def on_agent_connected(self, topic: str, agent_id: str): - self.connected_bidders += 1 - print(f"Bidder {agent_id} connected. {self.connected_bidders}/{self.expected_bidders} bidders connected.") - if self.connected_bidders == self.expected_bidders: - print("All bidders connected. Starting the auction.") - await self.start_auction() - - async def start_auction(self): - print(f"Starting auction for {self.item.name} with starting price ${self.item.starting_price}") - await self.broadcast_data(AuctionStart(item=self.item)) - - @on_message(type=Bid) - async def on_bid(self, bid: Bid): - self.bids.append(bid) - print(f"Received bid from {bid.bidder} for ${bid.amount:.2f}") - await self.end_auction() - - async def end_auction(self): - if not self.bids: - print(f"No bids received for {self.item.name}") - else: - winning_bid = max(self.bids, key=lambda x: x.amount) - result = AuctionResult(winner=winning_bid.bidder, winning_bid=winning_bid.amount) - await self.broadcast_data(result) - print(f"Auction ended. Winner: {result.winner}, Winning Bid: ${result.winning_bid:.2f}") - await self.stop() - - await self.broadcast_data(AuctionEnd()) - - -if __name__ == '__main__': - item = Item("Rare Painting", 1000) - - bidders = [ - Bidder("Alice", 1500), - Bidder("Bob", 1200), - Bidder("Charlie", 2000), - ] - - auctioneer = Auctioneer(item, expected_bidders=len(bidders)) - auctioneer.run_admin(inputs=b"", workers=bidders) diff --git a/bindings/ceylon/tests/test_worker/chat_group.py b/bindings/ceylon/tests/test_worker/chat_group.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/tests/test_worker/meeting_schedular.py b/bindings/ceylon/tests/test_worker/meeting_schedular.py deleted file mode 100644 index c4394158..00000000 --- a/bindings/ceylon/tests/test_worker/meeting_schedular.py +++ /dev/null @@ -1,156 +0,0 @@ -import asyncio -import pickle -from typing import List - -from loguru import logger -from pydantic.dataclasses import dataclass - -from ceylon import Agent, CoreAdmin, on_message - -admin_port = 8000 -admin_peer = "Coordinator" -workspace_id = "time_scheduling" - -# For libraries, should be your library's `__name__` - -logger.disable("ceylon.agent.common") - - -@dataclass(repr=True) -class Meeting: - name: str - date: str - duration: int - minimum_participants: int - - def __str__(self): - return f"{self.name} {self.date} {self.duration} {self.minimum_participants}" - - -@dataclass(repr=True) -class TimeSlot: - date: str - start_time: int - end_time: int - - @property - def duration(self): - return self.end_time - self.start_time - - def __str__(self): - return f"{self.date} {self.start_time}-{self.end_time}" - - def is_greater_than(self, other): - return self.end_time > other.end_time - - -@dataclass(repr=True) -class AvailabilityRequest: - time_slot: TimeSlot - - -@dataclass(repr=True) -class AvailabilityResponse: - owner: str - time_slot: TimeSlot - accepted: bool - - -class Participant(Agent): - name: str - available_times: List[TimeSlot] - - def __init__(self, name, available_times): - self.name = name - self.available_times = available_times - super().__init__(name=name, workspace_id=workspace_id, admin_peer=admin_peer, admin_port=admin_port) - - @on_message(type=AvailabilityRequest) - async def on_availability_request(self, data: AvailabilityRequest): - # Check if the time slot is available - if not any(self.is_overlap(slot, data.time_slot, data.time_slot.duration) for slot in self.available_times): - # print(f"Time slot {data.time_slot} is not available for {self.details().name}") - await self.broadcast_data( - AvailabilityResponse(owner=self.details().name, time_slot=data.time_slot, accepted=False)) - else: - # print(f"Time slot {data.time_slot} is available") - await self.broadcast_data( - AvailabilityResponse(owner=self.details().name, time_slot=data.time_slot, accepted=True)) - - @staticmethod - def is_overlap(slot1: TimeSlot, slot2: TimeSlot, duration: int) -> bool: - latest_start = max(slot1.start_time, slot2.start_time) - earliest_end = min(slot1.end_time, slot2.end_time) - return earliest_end - latest_start >= duration - - -class Coordinator(CoreAdmin): - meeting: Meeting = None - agreed_slots = {} - next_time_slot = None - - def __init__(self): - super().__init__(name=workspace_id, port=admin_port) - - @staticmethod - def is_overlap(slot1: TimeSlot, slot2: TimeSlot, duration: int) -> bool: - latest_start = max(slot1.start_time, slot2.start_time) - earliest_end = min(slot1.end_time, slot2.end_time) - return earliest_end - latest_start >= duration - - async def run(self, inputs: "bytes"): - self.meeting = pickle.loads(inputs) - print("Meeting Schedule request: ", self.meeting) - - async def on_agent_connected(self, topic: "str", agent_id: "str"): - if self.next_time_slot is None and self.meeting is not None: - self.next_time_slot = TimeSlot(self.meeting.date, 0, self.meeting.duration) - await self.broadcast_data(AvailabilityRequest(time_slot=self.next_time_slot)) - - @on_message(type=AvailabilityResponse) - async def on_availability_request(self, data: AvailabilityResponse): - await self.broadcast_data( - AvailabilityResponse(owner=self.details().name, time_slot=data.time_slot, accepted=True)) - - data: AvailabilityResponse = data - if data.accepted: - time_slot_key = f"{data.time_slot}" - print(f"{data.owner} accepts {data.time_slot}") - if time_slot_key in self.agreed_slots: - slots = self.agreed_slots[time_slot_key] - if data.owner not in slots: - slots.append(data.owner) - self.agreed_slots[time_slot_key] = slots - if len(slots) >= self.meeting.minimum_participants: - print(f"Meeting {slots} participants agreed on {data.time_slot}") - await self.stop() - else: - self.agreed_slots[time_slot_key] = [data.owner] - - current_time_slot = data.time_slot - calculated_next_time_slot = TimeSlot(self.meeting.date, current_time_slot.start_time + 1, - current_time_slot.start_time + 1 + self.meeting.duration) - - if calculated_next_time_slot.is_greater_than(self.next_time_slot): - self.next_time_slot = calculated_next_time_slot - # print(f"Next time slot: {self.next_time_slot}") - await self.broadcast_data(AvailabilityRequest(time_slot=self.next_time_slot)) - - -async def main(): - agent1 = Participant("Alice", [TimeSlot("2024-07-21", 9, 12), TimeSlot("2024-07-21", 14, 18)]) - agent2 = Participant("Bob", [TimeSlot("2024-07-21", 10, 13), TimeSlot("2024-07-21", 15, 17)]) - agent3 = Participant("Charlie", [TimeSlot("2024-07-21", 11, 14), TimeSlot("2024-07-21", 16, 18)]) - agent4 = Participant("David", [TimeSlot("2024-07-21", 11, 14), TimeSlot("2024-07-21", 16, 18)]) - agent5 = Participant("Kevin", [TimeSlot("2024-07-21", 10, 13), TimeSlot("2024-07-21", 15, 17)]) - - coordinator = Coordinator() - await coordinator.arun_admin( - inputs=pickle.dumps(Meeting(name="Meeting 1", duration=2, date="2024-07-21", minimum_participants=3)), - workers=[agent1, agent2, agent3, agent4, agent5] - ) - - -if __name__ == '__main__': - # enable_log("INFO") - asyncio.run(main()) diff --git a/bindings/ceylon/tests/test_worker/remote/__init__.py b/bindings/ceylon/tests/test_worker/remote/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/tests/test_worker/remote/remote_admin.py b/bindings/ceylon/tests/test_worker/remote/remote_admin.py deleted file mode 100644 index 7ad8e770..00000000 --- a/bindings/ceylon/tests/test_worker/remote/remote_admin.py +++ /dev/null @@ -1,26 +0,0 @@ -import pickle - -from loguru import logger - -from ceylon import CoreAdmin, Agent -from ceylon.ceylon import AgentDetail - - -class ServerAdminAgent(CoreAdmin): - - async def on_agent_connected(self, topic: "str", agent: AgentDetail): - logger.info((f"ServerAdminAgent on_agent_connected {self.details().name}", agent.id, agent.name, agent.role)) - - -class WorkerAgent1(Agent): - - async def run(self, inputs: "bytes"): - logger.info((f"WorkerAgent1 on_run {self.details().name}", inputs)) - - -worker_1 = WorkerAgent1("worker_1", "server_admin", admin_port=8000) - -server_admin = ServerAdminAgent("server_admin", 8000, workers=[worker_1]) - -# enable_log("info") -server_admin.run_admin(pickle.dumps({}), [worker_1]) diff --git a/bindings/ceylon/tests/test_worker/remote/remote_worker.py b/bindings/ceylon/tests/test_worker/remote/remote_worker.py deleted file mode 100644 index 51fe5283..00000000 --- a/bindings/ceylon/tests/test_worker/remote/remote_worker.py +++ /dev/null @@ -1,18 +0,0 @@ -import pickle - -from loguru import logger - -from ceylon import Agent - - -class WorkerAgent1(Agent): - - async def run(self, inputs: "bytes"): - logger.info((f"WorkerAgent1 on_run {self.details().name}", inputs)) - - -worker_1 = WorkerAgent1("worker_2", "server_admin", role="What enver", admin_port=8000, - admin_peer="12D3KooWCLKVyiM5VkwYYAaDKL5rMW4WnSbMcVicMDqy23inFz3K") - - -worker_1.run_worker(pickle.dumps({})) diff --git a/bindings/ceylon/tests/test_worker/task_manager.py b/bindings/ceylon/tests/test_worker/task_manager.py deleted file mode 100644 index a974e2ef..00000000 --- a/bindings/ceylon/tests/test_worker/task_manager.py +++ /dev/null @@ -1,100 +0,0 @@ -# Distributed Task Management System - -import asyncio -from typing import List -from pydantic.dataclasses import dataclass -from ceylon import Agent, CoreAdmin, on_message -from loguru import logger - -from ceylon.ceylon import AgentDetail - - -# Data structures -@dataclass -class Task: - id: int - description: str - difficulty: int # 1-10 scale - - -@dataclass -class TaskAssignment: - task: Task - - -@dataclass -class TaskResult: - task_id: int - worker: str - success: bool - - -# Worker Agent -class WorkerAgent(Agent): - def __init__(self, name: str, skill_level: int): - self.name = name - self.skill_level = skill_level - super().__init__(name=name, workspace_id="task_management", admin_port=8000) - - @on_message(type=TaskAssignment) - async def on_task_assignment(self, data: TaskAssignment): - logger.info(f"{self.name} received task: {data.task.description}") - # Simulate task execution - await asyncio.sleep(data.task.difficulty) - success = self.skill_level >= data.task.difficulty - await self.broadcast_data(TaskResult(task_id=data.task.id, worker=self.name, success=success)) - - -# Task Manager -class TaskManager(CoreAdmin): - tasks: List[Task] = [] - workers: List[WorkerAgent] = [] - task_results: List[TaskResult] = [] - - def __init__(self, tasks: List[Task], workers: List[WorkerAgent]): - self.workers = workers - self.tasks = tasks - super().__init__(name="task_management", port=8000) - - async def on_agent_connected(self, topic: str, agent_id: AgentDetail): - logger.info(f"Worker {agent_id} connected") - if len(self.workers) == len(self.tasks): - await self.assign_tasks() - - async def assign_tasks(self): - for task, worker in zip(self.tasks, self.workers): - await self.broadcast_data(TaskAssignment(task=task)) - - @on_message(type=TaskResult) - async def on_task_result(self, result: TaskResult): - self.task_results.append(result) - logger.info( - f"Received result for task {result.task_id} from {result.worker}: {'Success' if result.success else 'Failure'}") - if len(self.task_results) == len(self.tasks): - await self.end_task_management() - - async def end_task_management(self): - success_rate = sum(1 for result in self.task_results if result.success) / len(self.task_results) - logger.info(f"All tasks completed. Success rate: {success_rate:.2%}") - await self.stop() - - -# Main execution -if __name__ == '__main__': - # Create tasks - tasks = [ - Task(id=1, description="Simple calculation", difficulty=2), - Task(id=2, description="Data analysis", difficulty=5), - Task(id=3, description="Machine learning model training", difficulty=8), - ] - - # Create workers - workers = [ - WorkerAgent("Junior", skill_level=3), - WorkerAgent("Intermediate", skill_level=6), - WorkerAgent("Senior", skill_level=9), - ] - - # Create and run task manager - task_manager = TaskManager(tasks, workers) - task_manager.run_admin(inputs=b"", workers=workers) diff --git a/bindings/ceylon/tests/test_worker/test.py b/bindings/ceylon/tests/test_worker/test.py deleted file mode 100644 index 5df37f28..00000000 --- a/bindings/ceylon/tests/test_worker/test.py +++ /dev/null @@ -1,86 +0,0 @@ -import asyncio -import pickle - -from loguru import logger -from pydantic import BaseModel - -from ceylon import on_message, Agent, CoreAdmin - - -class MessageType1(BaseModel): - title: str - - -class MessageType2(BaseModel): - name: str - - -class TestAdmin(CoreAdmin): - - @on_message(type=MessageType1) - async def on_message_type_one(self, message: MessageType1, agent_id: "str", time: "int"): - logger.info((f"TestAdmin Message type one", message)) - - @on_message(type=MessageType2) - async def on_message_type_two(self, message: MessageType2, agent_id: "str", time: "int"): - logger.info((f"TestAdmin Message type two", message)) - - async def run(self, inputs: "bytes"): - while True: - await asyncio.sleep(5) - await self.broadcast(pickle.dumps(MessageType2(name="Im Admin"))) - - -class TestWorker(Agent): - - @on_message(type=MessageType1) - async def on_message_type_test_worker(self, message: MessageType1, agent_id: "str", time: "int"): - logger.info((f"TestWorker {self.details().name} Message type one {self.details().name}", message)) - - @on_message(type=MessageType2) - async def on_message_type_two_test_worker(self, message: MessageType2, agent_id: "str", time: "int"): - logger.info((f"TestWorker {self.details().name} Message type two {self.details().name}", message)) - - async def run(self, inputs: "bytes"): - while True: - await asyncio.sleep(1) - await self.broadcast(pickle.dumps(MessageType2(name=f"Im Worker {self.details().name}"))) - - -async def main(): - admin = TestAdmin( - name="admin", - port=8000 - ) - worker1 = TestWorker( - name="worker1", - admin_port=8000, - admin_peer="admin", - workspace_id="admin" - ) - worker2 = TestWorker( - name="worker2", - admin_port=8000, - admin_peer="admin", - workspace_id="admin" - ) - - worker3 = TestWorker( - name="worker3", - admin_port=8000, - admin_peer="admin", - workspace_id="admin" - ) - - await admin.arun_admin(pickle.dumps({ - "title": "How to use AI for Machine Learning", - }), [ - worker1, - worker2, - worker3 - ]) - - -if __name__ == '__main__': - # enable_log("INFO") - asyncio.run(main()) diff --git a/bindings/ceylon/tests/test_worker/test_game_board.py b/bindings/ceylon/tests/test_worker/test_game_board.py deleted file mode 100644 index 122ac1cf..00000000 --- a/bindings/ceylon/tests/test_worker/test_game_board.py +++ /dev/null @@ -1,80 +0,0 @@ -import random - - -# Define the roles and their abilities -class Role: - def __init__(self, name, ability): - self.name = name - self.ability = ability - - -class Player: - def __init__(self, name, role): - self.name = name - self.role = role - self.clues = [] - self.position = 'Foyer' - - def move(self, new_position): - self.position = new_position - print(f"{self.name} moves to the {new_position}") - - def find_clue(self, clue): - - self.clues.append(clue) - print(f"{self.name} found a clue: {clue}") - - -# Define the mansion layout and clues -rooms = ['Library', 'Lab', 'Attic', 'Kitchen', 'Garden'] -clues = { - 'Library': 'Ancient Book', - 'Lab': 'Strange Chemical', - 'Attic': 'Old Journal', - 'Kitchen': 'Hidden Key', - 'Garden': 'Mysterious Map' -} - -# Define the players -roles = [ - Role('Detective', 'Can ask detailed questions about clues'), - Role('Scientist', 'Can analyze clues for additional insights'), - Role('Historian', 'Knows the mansion\'s background'), - Role('Locksmith', 'Can open hidden rooms and safes'), - Role('Psychic', 'Can sense hidden items and passages'), - Role('Thief', 'Can retrieve items from locked areas') -] - -players = [ - Player('Alice', roles[0]), - Player('Bob', roles[1]), - Player('Charlie', roles[2]), - Player('Diana', roles[3]), - Player('Eve', roles[4]), - Player('Frank', roles[5]) -] - - -# Simulate a few turns -def simulate_game_turns(turns): - for turn in range(turns): - print(f"\nTurn {turn + 1}") - for player in players: - # Randomly move the player to a new room - new_room = random.choice(rooms) - player.move(new_room) - - # Check if there's a clue in the room - if new_room in clues: - player.find_clue(clues[new_room]) - # Remove the clue from the room (assuming it's found only once) - del clues[new_room] - - -# Run the simulation for 5 turns -simulate_game_turns(5) - -# Print the final state -print("\nFinal State:") -for player in players: - print(f"{player.name} ({player.role.name}) has clues: {player.clues}") diff --git a/bindings/ceylon/tests/tools/__init__.py b/bindings/ceylon/tests/tools/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/ceylon/tests/tools/file_publisher_tool_test.py b/bindings/ceylon/tests/tools/file_publisher_tool_test.py deleted file mode 100644 index 25e1fdc1..00000000 --- a/bindings/ceylon/tests/tools/file_publisher_tool_test.py +++ /dev/null @@ -1,55 +0,0 @@ -import unittest -from unittest.mock import Mock, patch - -from langchain_community.llms.ollama import Ollama - -from ceylon.ceylon import AgentDefinition -from ceylon.llm.llm_caller import process_agent_request -from ceylon.tools.search_tool import SearchTool - - -class TestProcessAgentRequest(unittest.TestCase): - - def setUp(self): - self.llm = Ollama(model="phi3:instruct") - self.search_tool = SearchTool() - self.tools = [self.search_tool] - - @patch('ceylon.llm.llm_caller.process_agent_request') - def test_process_agent_request(self, mock_process_agent_request): - # Arrange - expected_result = "Mocked result of process_agent_request" - mock_process_agent_request.return_value = expected_result - - inputs = {"task_info": "How LLM Work"} - agent_definition = AgentDefinition( - name="Agent 1", - position="Content Publisher", - responsibilities=[ - "Write content based on the given topic.", - "Write content to file", - ], - instructions=[ - "Write given content in a clear and concise manner.", - ], - id="Agent 1" - ) - - # Act - result = process_agent_request( - self.llm, - inputs=inputs, - agent_definition=agent_definition, - tools=self.tools - ) - - print(result) - - def test_ollama_initialization(self): - # Arrange - expected_model = "phi3:instruct" - - llm = Ollama(model=expected_model) - - # Assert - self.assertEqual(llm.model, expected_model)