flowent 0.0.7 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -3
- package/backend/README.md +0 -3
- package/backend/pyproject.toml +2 -8
- package/backend/src/flowent/__pycache__/__init__.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/agent.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/cli.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/context.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/llm.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/logging.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/main.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/patch.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/paths.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/sandbox.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/storage.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/tools.cpython-313.pyc +0 -0
- package/backend/src/flowent/agent.py +213 -3173
- package/backend/src/flowent/cli.py +19 -24
- package/backend/src/flowent/context.py +127 -0
- package/backend/src/flowent/llm.py +256 -0
- package/backend/src/flowent/logging.py +170 -129
- package/backend/src/flowent/main.py +321 -70
- package/backend/src/flowent/patch.py +182 -0
- package/backend/src/flowent/paths.py +11 -0
- package/backend/src/flowent/sandbox.py +214 -40
- package/backend/src/flowent/static/assets/geist-cyrillic-wght-normal-CHSlOQsW.woff2 +0 -0
- package/backend/src/flowent/static/assets/geist-latin-ext-wght-normal-DMtmJ5ZE.woff2 +0 -0
- package/backend/src/flowent/static/assets/geist-latin-wght-normal-Dm3htQBi.woff2 +0 -0
- package/backend/src/flowent/static/assets/index-C76K95ty.js +81 -0
- package/backend/src/flowent/static/assets/index-iUMNKvlU.css +2 -0
- package/backend/src/flowent/static/flowent.png +0 -0
- package/backend/src/flowent/static/index.html +5 -25
- package/backend/src/flowent/storage.py +302 -0
- package/backend/src/flowent/tools.py +364 -0
- package/backend/tests/__pycache__/test_agent_tools.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/__pycache__/test_health.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/__pycache__/test_llm_providers.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/__pycache__/test_logging.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/__pycache__/test_persistence.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/__pycache__/test_workspace_chat.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/test_agent_tools.py +449 -0
- package/backend/tests/test_health.py +12 -0
- package/backend/tests/test_llm_providers.py +113 -0
- package/backend/tests/test_logging.py +182 -0
- package/backend/tests/test_persistence.py +125 -0
- package/backend/tests/test_workspace_chat.py +578 -0
- package/backend/uv.lock +803 -99
- package/dist/frontend/assets/geist-cyrillic-wght-normal-CHSlOQsW.woff2 +0 -0
- package/dist/frontend/assets/geist-latin-ext-wght-normal-DMtmJ5ZE.woff2 +0 -0
- package/dist/frontend/assets/geist-latin-wght-normal-Dm3htQBi.woff2 +0 -0
- package/dist/frontend/assets/index-C76K95ty.js +81 -0
- package/dist/frontend/assets/index-iUMNKvlU.css +2 -0
- package/dist/frontend/flowent.png +0 -0
- package/dist/frontend/index.html +5 -25
- package/package.json +1 -2
- package/backend/src/flowent/__pycache__/_version.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/access.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/assistant_commands.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/config.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/events.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/graph_runtime.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/graph_service.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/image_assets.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/model_metadata.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/network.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/observability_service.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/registry.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/role_management.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/runtime.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/security.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/settings.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/settings_management.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/state_db.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/workspace_store.cpython-313.pyc +0 -0
- package/backend/src/flowent/access.py +0 -247
- package/backend/src/flowent/assistant_commands.py +0 -115
- package/backend/src/flowent/channels/__init__.py +0 -3
- package/backend/src/flowent/channels/__pycache__/__init__.cpython-313.pyc +0 -0
- package/backend/src/flowent/channels/__pycache__/telegram.cpython-313.pyc +0 -0
- package/backend/src/flowent/channels/telegram.py +0 -615
- package/backend/src/flowent/config.py +0 -14
- package/backend/src/flowent/dev.py +0 -3
- package/backend/src/flowent/events.py +0 -157
- package/backend/src/flowent/graph_runtime.py +0 -60
- package/backend/src/flowent/graph_service.py +0 -2401
- package/backend/src/flowent/image_assets.py +0 -356
- package/backend/src/flowent/model_metadata.py +0 -102
- package/backend/src/flowent/models/__init__.py +0 -125
- package/backend/src/flowent/models/__pycache__/__init__.cpython-313.pyc +0 -0
- package/backend/src/flowent/models/__pycache__/agent.cpython-313.pyc +0 -0
- package/backend/src/flowent/models/__pycache__/base.cpython-313.pyc +0 -0
- package/backend/src/flowent/models/__pycache__/blueprint.cpython-313.pyc +0 -0
- package/backend/src/flowent/models/__pycache__/content.cpython-313.pyc +0 -0
- package/backend/src/flowent/models/__pycache__/delta.cpython-313.pyc +0 -0
- package/backend/src/flowent/models/__pycache__/event.cpython-313.pyc +0 -0
- package/backend/src/flowent/models/__pycache__/graph.cpython-313.pyc +0 -0
- package/backend/src/flowent/models/__pycache__/history.cpython-313.pyc +0 -0
- package/backend/src/flowent/models/__pycache__/llm.cpython-313.pyc +0 -0
- package/backend/src/flowent/models/__pycache__/message.cpython-313.pyc +0 -0
- package/backend/src/flowent/models/__pycache__/tab.cpython-313.pyc +0 -0
- package/backend/src/flowent/models/__pycache__/todo.cpython-313.pyc +0 -0
- package/backend/src/flowent/models/agent.py +0 -34
- package/backend/src/flowent/models/base.py +0 -24
- package/backend/src/flowent/models/blueprint.py +0 -176
- package/backend/src/flowent/models/content.py +0 -164
- package/backend/src/flowent/models/delta.py +0 -44
- package/backend/src/flowent/models/event.py +0 -51
- package/backend/src/flowent/models/graph.py +0 -472
- package/backend/src/flowent/models/history.py +0 -272
- package/backend/src/flowent/models/llm.py +0 -62
- package/backend/src/flowent/models/message.py +0 -33
- package/backend/src/flowent/models/tab.py +0 -85
- package/backend/src/flowent/models/todo.py +0 -10
- package/backend/src/flowent/network.py +0 -146
- package/backend/src/flowent/observability_service.py +0 -218
- package/backend/src/flowent/prompts/__init__.py +0 -67
- package/backend/src/flowent/prompts/__pycache__/__init__.cpython-313.pyc +0 -0
- package/backend/src/flowent/prompts/__pycache__/common.cpython-313.pyc +0 -0
- package/backend/src/flowent/prompts/__pycache__/steward.cpython-313.pyc +0 -0
- package/backend/src/flowent/prompts/common.py +0 -250
- package/backend/src/flowent/prompts/steward.py +0 -64
- package/backend/src/flowent/providers/__init__.py +0 -23
- package/backend/src/flowent/providers/__pycache__/__init__.cpython-313.pyc +0 -0
- package/backend/src/flowent/providers/__pycache__/anthropic.cpython-313.pyc +0 -0
- package/backend/src/flowent/providers/__pycache__/base_url.cpython-313.pyc +0 -0
- package/backend/src/flowent/providers/__pycache__/configuration.cpython-313.pyc +0 -0
- package/backend/src/flowent/providers/__pycache__/content.cpython-313.pyc +0 -0
- package/backend/src/flowent/providers/__pycache__/errors.cpython-313.pyc +0 -0
- package/backend/src/flowent/providers/__pycache__/gateway.cpython-313.pyc +0 -0
- package/backend/src/flowent/providers/__pycache__/headers.cpython-313.pyc +0 -0
- package/backend/src/flowent/providers/__pycache__/management.cpython-313.pyc +0 -0
- package/backend/src/flowent/providers/__pycache__/openai.cpython-313.pyc +0 -0
- package/backend/src/flowent/providers/__pycache__/openai_responses.cpython-313.pyc +0 -0
- package/backend/src/flowent/providers/__pycache__/registry.cpython-313.pyc +0 -0
- package/backend/src/flowent/providers/__pycache__/sse.cpython-313.pyc +0 -0
- package/backend/src/flowent/providers/__pycache__/thinking.cpython-313.pyc +0 -0
- package/backend/src/flowent/providers/anthropic.py +0 -468
- package/backend/src/flowent/providers/base_url.py +0 -60
- package/backend/src/flowent/providers/configuration.py +0 -189
- package/backend/src/flowent/providers/content.py +0 -122
- package/backend/src/flowent/providers/errors.py +0 -223
- package/backend/src/flowent/providers/gateway.py +0 -169
- package/backend/src/flowent/providers/gemini.py +0 -447
- package/backend/src/flowent/providers/headers.py +0 -20
- package/backend/src/flowent/providers/management.py +0 -96
- package/backend/src/flowent/providers/ollama.py +0 -293
- package/backend/src/flowent/providers/openai.py +0 -422
- package/backend/src/flowent/providers/openai_responses.py +0 -655
- package/backend/src/flowent/providers/registry.py +0 -144
- package/backend/src/flowent/providers/sse.py +0 -31
- package/backend/src/flowent/providers/thinking.py +0 -79
- package/backend/src/flowent/registry.py +0 -73
- package/backend/src/flowent/role_management.py +0 -270
- package/backend/src/flowent/routes/__init__.py +0 -26
- package/backend/src/flowent/routes/__pycache__/__init__.cpython-313.pyc +0 -0
- package/backend/src/flowent/routes/__pycache__/access.cpython-313.pyc +0 -0
- package/backend/src/flowent/routes/__pycache__/assistant.cpython-313.pyc +0 -0
- package/backend/src/flowent/routes/__pycache__/image_assets.cpython-313.pyc +0 -0
- package/backend/src/flowent/routes/__pycache__/meta.cpython-313.pyc +0 -0
- package/backend/src/flowent/routes/__pycache__/nodes.cpython-313.pyc +0 -0
- package/backend/src/flowent/routes/__pycache__/prompts.cpython-313.pyc +0 -0
- package/backend/src/flowent/routes/__pycache__/providers_route.cpython-313.pyc +0 -0
- package/backend/src/flowent/routes/__pycache__/roles.cpython-313.pyc +0 -0
- package/backend/src/flowent/routes/__pycache__/settings.cpython-313.pyc +0 -0
- package/backend/src/flowent/routes/__pycache__/tabs.cpython-313.pyc +0 -0
- package/backend/src/flowent/routes/__pycache__/ws.cpython-313.pyc +0 -0
- package/backend/src/flowent/routes/access.py +0 -48
- package/backend/src/flowent/routes/assistant.py +0 -158
- package/backend/src/flowent/routes/image_assets.py +0 -33
- package/backend/src/flowent/routes/meta.py +0 -28
- package/backend/src/flowent/routes/nodes.py +0 -423
- package/backend/src/flowent/routes/prompts.py +0 -46
- package/backend/src/flowent/routes/providers_route.py +0 -365
- package/backend/src/flowent/routes/roles.py +0 -207
- package/backend/src/flowent/routes/settings.py +0 -379
- package/backend/src/flowent/routes/tabs.py +0 -298
- package/backend/src/flowent/routes/ws.py +0 -33
- package/backend/src/flowent/runtime.py +0 -160
- package/backend/src/flowent/security.py +0 -37
- package/backend/src/flowent/settings.py +0 -2112
- package/backend/src/flowent/settings_management.py +0 -394
- package/backend/src/flowent/state_db.py +0 -108
- package/backend/src/flowent/static/assets/AssistantPage-BW7XAd9I.js +0 -1
- package/backend/src/flowent/static/assets/ChannelsPage-tCJHgt6m.js +0 -1
- package/backend/src/flowent/static/assets/PageScaffold-f6g2l7XN.js +0 -1
- package/backend/src/flowent/static/assets/PromptsPage-C3Sxn2D7.js +0 -1
- package/backend/src/flowent/static/assets/ProvidersPage-BfmdXmNt.js +0 -3
- package/backend/src/flowent/static/assets/RolesPage-DET8wO4r.js +0 -1
- package/backend/src/flowent/static/assets/SettingsPage-D-g3deMm.js +0 -3
- package/backend/src/flowent/static/assets/ToolsPage-CDmtE2g4.js +0 -1
- package/backend/src/flowent/static/assets/WorkspacePage-AZsJ0sD0.js +0 -3
- package/backend/src/flowent/static/assets/WorkspacePanels-CteCjolX.js +0 -1
- package/backend/src/flowent/static/assets/alert-dialog-Duorp_S-.js +0 -1
- package/backend/src/flowent/static/assets/dialog-C3ixjGjN.js +0 -1
- package/backend/src/flowent/static/assets/elk-worker.min-C9JGDOE-.js +0 -6312
- package/backend/src/flowent/static/assets/graph-vendor-CHpVij2M.css +0 -1
- package/backend/src/flowent/static/assets/graph-vendor-DRq_-6fV.js +0 -7
- package/backend/src/flowent/static/assets/index--o_0fv0N.css +0 -1
- package/backend/src/flowent/static/assets/index-C9HuekJm.js +0 -10
- package/backend/src/flowent/static/assets/layout.worker-jMHqAFbP.js +0 -24
- package/backend/src/flowent/static/assets/markdown-vendor-C9RtvaJh.js +0 -29
- package/backend/src/flowent/static/assets/modelParams-DmnF2hwR.js +0 -1
- package/backend/src/flowent/static/assets/providerTypes-DT3Ahwl_.js +0 -1
- package/backend/src/flowent/static/assets/react-vendor-mEs_JJxa.js +0 -9
- package/backend/src/flowent/static/assets/roles-CuRT_chR.js +0 -1
- package/backend/src/flowent/static/assets/rolldown-runtime-BYbx6iT9.js +0 -1
- package/backend/src/flowent/static/assets/select-DCfeNu-F.js +0 -1
- package/backend/src/flowent/static/assets/surface-pWwG5ogx.js +0 -1
- package/backend/src/flowent/static/assets/ui-vendor-C5pJa8N7.js +0 -51
- package/backend/src/flowent/static/assets/useAppRoute-FgSHBKhV.js +0 -1
- package/backend/src/flowent/static/favicon.svg +0 -4
- package/backend/src/flowent/tools/__init__.py +0 -176
- package/backend/src/flowent/tools/__pycache__/__init__.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/connect.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/contacts.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/create_agent.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/create_tab.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/delete_tab.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/edit.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/exec.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/fetch.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/idle.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/list_roles.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/list_tabs.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/list_tools.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/manage_prompts.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/manage_providers.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/manage_roles.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/manage_settings.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/read.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/send.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/set_permissions.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/sleep.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/__pycache__/todo.cpython-313.pyc +0 -0
- package/backend/src/flowent/tools/connect.py +0 -100
- package/backend/src/flowent/tools/contacts.py +0 -22
- package/backend/src/flowent/tools/create_agent.py +0 -191
- package/backend/src/flowent/tools/create_tab.py +0 -61
- package/backend/src/flowent/tools/delete_tab.py +0 -39
- package/backend/src/flowent/tools/edit.py +0 -142
- package/backend/src/flowent/tools/exec.py +0 -118
- package/backend/src/flowent/tools/fetch.py +0 -85
- package/backend/src/flowent/tools/idle.py +0 -27
- package/backend/src/flowent/tools/list_roles.py +0 -68
- package/backend/src/flowent/tools/list_tabs.py +0 -100
- package/backend/src/flowent/tools/list_tools.py +0 -28
- package/backend/src/flowent/tools/manage_prompts.py +0 -102
- package/backend/src/flowent/tools/manage_providers.py +0 -220
- package/backend/src/flowent/tools/manage_roles.py +0 -275
- package/backend/src/flowent/tools/manage_settings.py +0 -326
- package/backend/src/flowent/tools/read.py +0 -152
- package/backend/src/flowent/tools/send.py +0 -68
- package/backend/src/flowent/tools/set_permissions.py +0 -99
- package/backend/src/flowent/tools/sleep.py +0 -41
- package/backend/src/flowent/tools/todo.py +0 -51
- package/backend/src/flowent/workspace_store.py +0 -479
- package/backend/tests/__init__.py +0 -0
- package/backend/tests/__pycache__/__init__.cpython-313.pyc +0 -0
- package/backend/tests/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/conftest.py +0 -6
- package/backend/tests/integration/api/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/integration/api/__pycache__/test_access_api.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/integration/api/__pycache__/test_assistant_api.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/integration/api/__pycache__/test_frontend_mounting.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/integration/api/__pycache__/test_meta_api.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/integration/api/__pycache__/test_nodes_api.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/integration/api/__pycache__/test_prompts_api.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/integration/api/__pycache__/test_roles_api.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/integration/api/__pycache__/test_tabs_api.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/integration/api/conftest.py +0 -29
- package/backend/tests/integration/api/test_access_api.py +0 -182
- package/backend/tests/integration/api/test_assistant_api.py +0 -422
- package/backend/tests/integration/api/test_frontend_mounting.py +0 -61
- package/backend/tests/integration/api/test_meta_api.py +0 -32
- package/backend/tests/integration/api/test_nodes_api.py +0 -787
- package/backend/tests/integration/api/test_prompts_api.py +0 -47
- package/backend/tests/integration/api/test_roles_api.py +0 -228
- package/backend/tests/integration/api/test_tabs_api.py +0 -688
- package/backend/tests/unit/__pycache__/test_access.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/__pycache__/test_cli.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/__pycache__/test_graph_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/__pycache__/test_network.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/__pycache__/test_state_sqlite_storage.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/__pycache__/test_workspace_store.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/agent/__pycache__/test_agent_public_api.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/agent/__pycache__/test_agent_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/agent/test_agent_public_api.py +0 -822
- package/backend/tests/unit/agent/test_agent_runtime.py +0 -3088
- package/backend/tests/unit/channels/__pycache__/test_telegram_channel.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/channels/test_telegram_channel.py +0 -552
- package/backend/tests/unit/logging/__pycache__/test_logging.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/logging/test_logging.py +0 -132
- package/backend/tests/unit/prompts/__pycache__/test_prompts.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/prompts/test_prompts.py +0 -570
- package/backend/tests/unit/providers/__pycache__/test_anthropic_provider.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/providers/__pycache__/test_errors.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/providers/__pycache__/test_extract_delta_parts.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/providers/__pycache__/test_openai_provider.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/providers/__pycache__/test_openai_responses.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/providers/__pycache__/test_provider_gateway.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/providers/__pycache__/test_think_tag_parser.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/providers/test_anthropic_provider.py +0 -185
- package/backend/tests/unit/providers/test_errors.py +0 -68
- package/backend/tests/unit/providers/test_extract_delta_parts.py +0 -22
- package/backend/tests/unit/providers/test_openai_provider.py +0 -139
- package/backend/tests/unit/providers/test_openai_responses.py +0 -402
- package/backend/tests/unit/providers/test_provider_gateway.py +0 -359
- package/backend/tests/unit/providers/test_think_tag_parser.py +0 -36
- package/backend/tests/unit/routes/__pycache__/test_prompts_routes.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/routes/__pycache__/test_providers_route.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/routes/__pycache__/test_roles_routes.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/routes/__pycache__/test_settings_routes.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/routes/test_prompts_routes.py +0 -82
- package/backend/tests/unit/routes/test_providers_route.py +0 -370
- package/backend/tests/unit/routes/test_roles_routes.py +0 -539
- package/backend/tests/unit/routes/test_settings_routes.py +0 -1123
- package/backend/tests/unit/runtime/__pycache__/test_bootstrap_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/runtime/test_bootstrap_runtime.py +0 -1002
- package/backend/tests/unit/sandbox/__pycache__/test_sandbox_tools.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/sandbox/test_sandbox_tools.py +0 -78
- package/backend/tests/unit/security/__pycache__/test_security.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/security/test_security.py +0 -124
- package/backend/tests/unit/settings/__pycache__/test_settings_roles.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/settings/test_settings_roles.py +0 -703
- package/backend/tests/unit/test_access.py +0 -45
- package/backend/tests/unit/test_cli.py +0 -102
- package/backend/tests/unit/test_graph_runtime.py +0 -72
- package/backend/tests/unit/test_network.py +0 -51
- package/backend/tests/unit/test_state_sqlite_storage.py +0 -87
- package/backend/tests/unit/test_workspace_store.py +0 -228
- package/backend/tests/unit/tools/__pycache__/test_connect_tool.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/tools/__pycache__/test_create_agent_tool.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/tools/__pycache__/test_delete_tab_tool.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/tools/__pycache__/test_edit_tool.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/tools/__pycache__/test_exec_tool.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/tools/__pycache__/test_fetch_tool.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/tools/__pycache__/test_manage_prompts_tool.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/tools/__pycache__/test_manage_providers_tool.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/tools/__pycache__/test_manage_roles_tool.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/tools/__pycache__/test_manage_settings_tool.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/tools/__pycache__/test_read_tool.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/tools/__pycache__/test_set_permissions_tool.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/tools/__pycache__/test_todo_tool.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/tools/__pycache__/test_tool_registry.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/unit/tools/test_connect_tool.py +0 -228
- package/backend/tests/unit/tools/test_create_agent_tool.py +0 -404
- package/backend/tests/unit/tools/test_delete_tab_tool.py +0 -116
- package/backend/tests/unit/tools/test_edit_tool.py +0 -115
- package/backend/tests/unit/tools/test_exec_tool.py +0 -81
- package/backend/tests/unit/tools/test_fetch_tool.py +0 -65
- package/backend/tests/unit/tools/test_manage_prompts_tool.py +0 -92
- package/backend/tests/unit/tools/test_manage_providers_tool.py +0 -460
- package/backend/tests/unit/tools/test_manage_roles_tool.py +0 -411
- package/backend/tests/unit/tools/test_manage_settings_tool.py +0 -611
- package/backend/tests/unit/tools/test_read_tool.py +0 -33
- package/backend/tests/unit/tools/test_set_permissions_tool.py +0 -595
- package/backend/tests/unit/tools/test_todo_tool.py +0 -37
- package/backend/tests/unit/tools/test_tool_registry.py +0 -199
- package/dist/frontend/assets/AssistantPage-BW7XAd9I.js +0 -1
- package/dist/frontend/assets/ChannelsPage-tCJHgt6m.js +0 -1
- package/dist/frontend/assets/PageScaffold-f6g2l7XN.js +0 -1
- package/dist/frontend/assets/PromptsPage-C3Sxn2D7.js +0 -1
- package/dist/frontend/assets/ProvidersPage-BfmdXmNt.js +0 -3
- package/dist/frontend/assets/RolesPage-DET8wO4r.js +0 -1
- package/dist/frontend/assets/SettingsPage-D-g3deMm.js +0 -3
- package/dist/frontend/assets/ToolsPage-CDmtE2g4.js +0 -1
- package/dist/frontend/assets/WorkspacePage-AZsJ0sD0.js +0 -3
- package/dist/frontend/assets/WorkspacePanels-CteCjolX.js +0 -1
- package/dist/frontend/assets/alert-dialog-Duorp_S-.js +0 -1
- package/dist/frontend/assets/dialog-C3ixjGjN.js +0 -1
- package/dist/frontend/assets/elk-worker.min-C9JGDOE-.js +0 -6312
- package/dist/frontend/assets/graph-vendor-CHpVij2M.css +0 -1
- package/dist/frontend/assets/graph-vendor-DRq_-6fV.js +0 -7
- package/dist/frontend/assets/index--o_0fv0N.css +0 -1
- package/dist/frontend/assets/index-C9HuekJm.js +0 -10
- package/dist/frontend/assets/layout.worker-jMHqAFbP.js +0 -24
- package/dist/frontend/assets/markdown-vendor-C9RtvaJh.js +0 -29
- package/dist/frontend/assets/modelParams-DmnF2hwR.js +0 -1
- package/dist/frontend/assets/providerTypes-DT3Ahwl_.js +0 -1
- package/dist/frontend/assets/react-vendor-mEs_JJxa.js +0 -9
- package/dist/frontend/assets/roles-CuRT_chR.js +0 -1
- package/dist/frontend/assets/rolldown-runtime-BYbx6iT9.js +0 -1
- package/dist/frontend/assets/select-DCfeNu-F.js +0 -1
- package/dist/frontend/assets/surface-pWwG5ogx.js +0 -1
- package/dist/frontend/assets/ui-vendor-C5pJa8N7.js +0 -51
- package/dist/frontend/assets/useAppRoute-FgSHBKhV.js +0 -1
- package/dist/frontend/favicon.svg +0 -4
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import copy
|
|
4
|
-
import json
|
|
5
|
-
import threading
|
|
6
|
-
import time
|
|
7
|
-
import uuid
|
|
8
|
-
from dataclasses import dataclass
|
|
9
|
-
from typing import Any, Literal
|
|
10
|
-
|
|
11
|
-
from flowent.models import LLMUsage
|
|
12
|
-
from flowent.state_db import open_state_db
|
|
13
|
-
|
|
14
|
-
OBSERVABILITY_RETENTION_SECONDS = 30 * 24 * 60 * 60
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def serialize_usage(usage: LLMUsage | None) -> dict[str, Any] | None:
|
|
18
|
-
if usage is None:
|
|
19
|
-
return None
|
|
20
|
-
return {
|
|
21
|
-
"total_tokens": usage.total_tokens,
|
|
22
|
-
"input_tokens": usage.input_tokens,
|
|
23
|
-
"output_tokens": usage.output_tokens,
|
|
24
|
-
"cached_input_tokens": usage.cached_input_tokens,
|
|
25
|
-
"cache_read_tokens": usage.cache_read_tokens,
|
|
26
|
-
"cache_write_tokens": usage.cache_write_tokens,
|
|
27
|
-
"details": dict(usage.details),
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
@dataclass(frozen=True)
|
|
32
|
-
class RequestRecordInput:
|
|
33
|
-
node_id: str
|
|
34
|
-
node_label: str
|
|
35
|
-
role_name: str | None
|
|
36
|
-
tab_id: str | None
|
|
37
|
-
tab_title: str | None
|
|
38
|
-
provider_id: str | None
|
|
39
|
-
provider_name: str | None
|
|
40
|
-
provider_type: str | None
|
|
41
|
-
model: str | None
|
|
42
|
-
started_at: float
|
|
43
|
-
ended_at: float
|
|
44
|
-
retry_count: int
|
|
45
|
-
result: Literal["success", "error"]
|
|
46
|
-
normalized_usage: LLMUsage | None = None
|
|
47
|
-
raw_usage: dict[str, Any] | None = None
|
|
48
|
-
error_summary: str | None = None
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
@dataclass(frozen=True)
|
|
52
|
-
class CompactRecordInput:
|
|
53
|
-
node_id: str
|
|
54
|
-
node_label: str
|
|
55
|
-
role_name: str | None
|
|
56
|
-
tab_id: str | None
|
|
57
|
-
tab_title: str | None
|
|
58
|
-
provider_id: str | None
|
|
59
|
-
provider_name: str | None
|
|
60
|
-
provider_type: str | None
|
|
61
|
-
model: str | None
|
|
62
|
-
trigger_type: Literal["manual", "auto"]
|
|
63
|
-
started_at: float
|
|
64
|
-
ended_at: float
|
|
65
|
-
result: Literal["success", "error"]
|
|
66
|
-
error_summary: str | None = None
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
class ObservabilityStore:
|
|
70
|
-
def __init__(self) -> None:
|
|
71
|
-
self._lock = threading.Lock()
|
|
72
|
-
|
|
73
|
-
def reset(self) -> None:
|
|
74
|
-
connection = open_state_db(create=False)
|
|
75
|
-
if connection is None:
|
|
76
|
-
return
|
|
77
|
-
try:
|
|
78
|
-
with connection:
|
|
79
|
-
connection.execute("DELETE FROM llm_request_records")
|
|
80
|
-
connection.execute("DELETE FROM compact_records")
|
|
81
|
-
finally:
|
|
82
|
-
connection.close()
|
|
83
|
-
|
|
84
|
-
def _prune_locked(self, connection, now: float) -> None:
|
|
85
|
-
min_timestamp = now - OBSERVABILITY_RETENTION_SECONDS
|
|
86
|
-
connection.execute(
|
|
87
|
-
"DELETE FROM llm_request_records WHERE ended_at < ?",
|
|
88
|
-
(min_timestamp,),
|
|
89
|
-
)
|
|
90
|
-
connection.execute(
|
|
91
|
-
"DELETE FROM compact_records WHERE ended_at < ?",
|
|
92
|
-
(min_timestamp,),
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
def record_request(self, record: RequestRecordInput) -> None:
|
|
96
|
-
payload = {
|
|
97
|
-
"id": str(uuid.uuid4()),
|
|
98
|
-
"node_id": record.node_id,
|
|
99
|
-
"node_label": record.node_label,
|
|
100
|
-
"role_name": record.role_name,
|
|
101
|
-
"tab_id": record.tab_id,
|
|
102
|
-
"tab_title": record.tab_title,
|
|
103
|
-
"provider_id": record.provider_id,
|
|
104
|
-
"provider_name": record.provider_name,
|
|
105
|
-
"provider_type": record.provider_type,
|
|
106
|
-
"model": record.model,
|
|
107
|
-
"started_at": record.started_at,
|
|
108
|
-
"ended_at": record.ended_at,
|
|
109
|
-
"duration_ms": max(0.0, (record.ended_at - record.started_at) * 1000),
|
|
110
|
-
"retry_count": max(record.retry_count, 0),
|
|
111
|
-
"result": record.result,
|
|
112
|
-
"error_summary": record.error_summary,
|
|
113
|
-
"normalized_usage": serialize_usage(record.normalized_usage),
|
|
114
|
-
"raw_usage": copy.deepcopy(record.raw_usage),
|
|
115
|
-
}
|
|
116
|
-
with self._lock:
|
|
117
|
-
connection = open_state_db(create=True)
|
|
118
|
-
assert connection is not None
|
|
119
|
-
try:
|
|
120
|
-
with connection:
|
|
121
|
-
self._prune_locked(connection, time.time())
|
|
122
|
-
connection.execute(
|
|
123
|
-
"""
|
|
124
|
-
INSERT INTO llm_request_records (id, ended_at, payload)
|
|
125
|
-
VALUES (?, ?, ?)
|
|
126
|
-
""",
|
|
127
|
-
(
|
|
128
|
-
payload["id"],
|
|
129
|
-
payload["ended_at"],
|
|
130
|
-
json.dumps(payload, ensure_ascii=False),
|
|
131
|
-
),
|
|
132
|
-
)
|
|
133
|
-
finally:
|
|
134
|
-
connection.close()
|
|
135
|
-
|
|
136
|
-
def record_compact(self, record: CompactRecordInput) -> None:
|
|
137
|
-
payload = {
|
|
138
|
-
"id": str(uuid.uuid4()),
|
|
139
|
-
"node_id": record.node_id,
|
|
140
|
-
"node_label": record.node_label,
|
|
141
|
-
"role_name": record.role_name,
|
|
142
|
-
"tab_id": record.tab_id,
|
|
143
|
-
"tab_title": record.tab_title,
|
|
144
|
-
"provider_id": record.provider_id,
|
|
145
|
-
"provider_name": record.provider_name,
|
|
146
|
-
"provider_type": record.provider_type,
|
|
147
|
-
"model": record.model,
|
|
148
|
-
"trigger_type": record.trigger_type,
|
|
149
|
-
"started_at": record.started_at,
|
|
150
|
-
"ended_at": record.ended_at,
|
|
151
|
-
"duration_ms": max(0.0, (record.ended_at - record.started_at) * 1000),
|
|
152
|
-
"result": record.result,
|
|
153
|
-
"error_summary": record.error_summary,
|
|
154
|
-
}
|
|
155
|
-
with self._lock:
|
|
156
|
-
connection = open_state_db(create=True)
|
|
157
|
-
assert connection is not None
|
|
158
|
-
try:
|
|
159
|
-
with connection:
|
|
160
|
-
self._prune_locked(connection, time.time())
|
|
161
|
-
connection.execute(
|
|
162
|
-
"""
|
|
163
|
-
INSERT INTO compact_records (id, ended_at, payload)
|
|
164
|
-
VALUES (?, ?, ?)
|
|
165
|
-
""",
|
|
166
|
-
(
|
|
167
|
-
payload["id"],
|
|
168
|
-
payload["ended_at"],
|
|
169
|
-
json.dumps(payload, ensure_ascii=False),
|
|
170
|
-
),
|
|
171
|
-
)
|
|
172
|
-
finally:
|
|
173
|
-
connection.close()
|
|
174
|
-
|
|
175
|
-
def list_requests(self, *, since: float) -> list[dict[str, Any]]:
|
|
176
|
-
with self._lock:
|
|
177
|
-
return self._list_records(
|
|
178
|
-
table_name="llm_request_records",
|
|
179
|
-
since=since,
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
def list_compacts(self, *, since: float) -> list[dict[str, Any]]:
|
|
183
|
-
with self._lock:
|
|
184
|
-
return self._list_records(
|
|
185
|
-
table_name="compact_records",
|
|
186
|
-
since=since,
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
def _list_records(self, *, table_name: str, since: float) -> list[dict[str, Any]]:
|
|
190
|
-
connection = open_state_db(create=False)
|
|
191
|
-
if connection is None:
|
|
192
|
-
return []
|
|
193
|
-
try:
|
|
194
|
-
with connection:
|
|
195
|
-
self._prune_locked(connection, time.time())
|
|
196
|
-
rows = connection.execute(
|
|
197
|
-
f"""
|
|
198
|
-
SELECT payload
|
|
199
|
-
FROM {table_name}
|
|
200
|
-
WHERE ended_at >= ?
|
|
201
|
-
ORDER BY ended_at
|
|
202
|
-
""",
|
|
203
|
-
(since,),
|
|
204
|
-
).fetchall()
|
|
205
|
-
finally:
|
|
206
|
-
connection.close()
|
|
207
|
-
records: list[dict[str, Any]] = []
|
|
208
|
-
for row in rows:
|
|
209
|
-
payload = row["payload"]
|
|
210
|
-
if not isinstance(payload, str):
|
|
211
|
-
continue
|
|
212
|
-
parsed = json.loads(payload)
|
|
213
|
-
if isinstance(parsed, dict):
|
|
214
|
-
records.append(parsed)
|
|
215
|
-
return records
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
observability_store = ObservabilityStore()
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from flowent.models import NodeConfig, NodeType
|
|
4
|
-
from flowent.prompts.common import DEFAULT_AGENT_ROLE_PROMPT, compose_system_prompt
|
|
5
|
-
from flowent.prompts.steward import STEWARD_ROLE_SYSTEM_PROMPT
|
|
6
|
-
from flowent.tools import MINIMUM_TOOLS
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def _get_assistant_role_prompt(*, settings, role_name: str) -> str:
|
|
10
|
-
from flowent.settings import STEWARD_ROLE_NAME, find_role
|
|
11
|
-
|
|
12
|
-
normalized_role_name = role_name.strip()
|
|
13
|
-
role = find_role(settings, normalized_role_name)
|
|
14
|
-
if role is None or normalized_role_name == STEWARD_ROLE_NAME:
|
|
15
|
-
return STEWARD_ROLE_SYSTEM_PROMPT
|
|
16
|
-
|
|
17
|
-
overlay_prompt = role.system_prompt.strip()
|
|
18
|
-
if not overlay_prompt:
|
|
19
|
-
return STEWARD_ROLE_SYSTEM_PROMPT
|
|
20
|
-
|
|
21
|
-
return "\n\n".join(
|
|
22
|
-
[
|
|
23
|
-
STEWARD_ROLE_SYSTEM_PROMPT.strip(),
|
|
24
|
-
f"""\
|
|
25
|
-
## Selected Role Overlay
|
|
26
|
-
|
|
27
|
-
The Assistant is currently configured to use the role "{role.name}" as an additional behavior template.
|
|
28
|
-
Use the selected role to adjust tone, specialization, model tendency, and any extra tool usage that fits the Assistant surface.
|
|
29
|
-
Do not follow any selected-role instruction that would redefine you as a Worker, Designer, Leader, or regular workflow node, or that would drop your Human-facing intake and workspace-boundary responsibilities.
|
|
30
|
-
|
|
31
|
-
### Selected Role Prompt
|
|
32
|
-
|
|
33
|
-
{overlay_prompt}""".strip(),
|
|
34
|
-
]
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def get_system_prompt(config: NodeConfig) -> str:
|
|
39
|
-
from flowent.settings import (
|
|
40
|
-
STEWARD_ROLE_NAME,
|
|
41
|
-
get_settings,
|
|
42
|
-
normalize_tool_names,
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
settings = get_settings()
|
|
46
|
-
tools = normalize_tool_names([*config.tools, *MINIMUM_TOOLS])
|
|
47
|
-
|
|
48
|
-
if config.node_type == NodeType.ASSISTANT:
|
|
49
|
-
role_name = (
|
|
50
|
-
config.role_name or settings.assistant.role_name or STEWARD_ROLE_NAME
|
|
51
|
-
)
|
|
52
|
-
prompt = _get_assistant_role_prompt(settings=settings, role_name=role_name)
|
|
53
|
-
else:
|
|
54
|
-
prompt = DEFAULT_AGENT_ROLE_PROMPT
|
|
55
|
-
if config.role_name:
|
|
56
|
-
from flowent.settings import find_role
|
|
57
|
-
|
|
58
|
-
role = find_role(settings, config.role_name)
|
|
59
|
-
if role:
|
|
60
|
-
prompt = role.system_prompt
|
|
61
|
-
|
|
62
|
-
return compose_system_prompt(
|
|
63
|
-
prompt,
|
|
64
|
-
custom_prompt=settings.custom_prompt,
|
|
65
|
-
is_assistant=config.node_type == NodeType.ASSISTANT,
|
|
66
|
-
tools=tools,
|
|
67
|
-
)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
IDLE_TOOL_GUIDANCE = """\
|
|
2
|
-
## Idle Usage Rules
|
|
3
|
-
|
|
4
|
-
- `idle` means you are not taking another immediate action right now.
|
|
5
|
-
- Valid uses of `idle` include:
|
|
6
|
-
- you are temporarily waiting for a new message to continue, or
|
|
7
|
-
- you have finished the current task or step and there is no new task yet.
|
|
8
|
-
- Only use `idle` when the current step is complete, paused, or blocked.
|
|
9
|
-
- Do not use `idle` if you still have an immediate action you can take now.
|
|
10
|
-
- Do not use `idle` instead of replying to a newly received message.
|
|
11
|
-
- After calling `idle`, you will be re-activated when a new message arrives.
|
|
12
|
-
- When that happens, the new message will appear as a fresh input message, and `idle` will return the idle duration.
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
SLEEP_TOOL_GUIDANCE = """\
|
|
16
|
-
## Sleep Usage Rules
|
|
17
|
-
|
|
18
|
-
- Use `sleep(seconds)` only for deliberate fixed-duration waiting.
|
|
19
|
-
- The `seconds` argument is measured in seconds and may be fractional.
|
|
20
|
-
- While `sleep` is in progress, incoming messages stay queued and are processed after the sleep finishes.
|
|
21
|
-
- Prefer `idle` when you are waiting for an unknown-duration incoming message or handoff.
|
|
22
|
-
- `sleep` returns the actual waited duration when it finishes.
|
|
23
|
-
- Do not use `sleep` instead of replying to a newly received message.
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
TODO_TOOL_GUIDANCE = """\
|
|
27
|
-
## Todo Tool Rules
|
|
28
|
-
|
|
29
|
-
- Use `todo` to manage your task checklist and track the current plan or remaining work.
|
|
30
|
-
"""
|
|
31
|
-
|
|
32
|
-
CREATE_WORKFLOW_TOOL_GUIDANCE = """\
|
|
33
|
-
## Create Workflow Tool Rules
|
|
34
|
-
|
|
35
|
-
- Use `create_workflow` to open a persistent workflow before building a Workflow Graph for that task.
|
|
36
|
-
- A workflow is the user-visible home for one task. Keep the title concrete and easy to recognize later.
|
|
37
|
-
"""
|
|
38
|
-
|
|
39
|
-
DELETE_WORKFLOW_TOOL_GUIDANCE = """\
|
|
40
|
-
## Delete Workflow Tool Rules
|
|
41
|
-
|
|
42
|
-
- Use `delete_workflow` only when the Human explicitly asks to remove a workflow or when you are intentionally cleaning up a task workspace that should no longer exist.
|
|
43
|
-
- Deleting a workflow permanently removes the workflow and its persisted Workflow Graph after active nodes are terminated.
|
|
44
|
-
"""
|
|
45
|
-
|
|
46
|
-
SET_PERMISSIONS_TOOL_GUIDANCE = """\
|
|
47
|
-
## Set Permissions Tool Rules
|
|
48
|
-
|
|
49
|
-
- Use `set_permissions` to patch a workflow's permission boundary after the workflow already exists.
|
|
50
|
-
- `set_permissions` updates the target workflow's own `allow_network` and `write_dirs`.
|
|
51
|
-
- Treat `allow_network` and `write_dirs` as patch fields: omitted fields stay unchanged.
|
|
52
|
-
- When the Human asks to change a workflow's network or writable directory boundary, prefer `set_permissions`.
|
|
53
|
-
"""
|
|
54
|
-
|
|
55
|
-
CREATE_AGENT_TOOL_GUIDANCE = """\
|
|
56
|
-
## Create Agent Tool Rules
|
|
57
|
-
|
|
58
|
-
- Use `create_agent` to add a new agent node to the current workflow.
|
|
59
|
-
- Prefer creating the right set of agents up front. If you also have `connect`, wire workflow edges as needed.
|
|
60
|
-
- `create_agent` always creates the new peer in your current workflow. It does not take `workflow_id` or any other cross-workflow target parameter.
|
|
61
|
-
- Ordinary task nodes may use `create_agent` only when that tool was explicitly granted to them.
|
|
62
|
-
- `create_agent` can place the new node as a standalone node, after another node, or between two nodes in the current Workflow Graph.
|
|
63
|
-
- Creating an agent does not start work by itself; explicitly dispatch its first task with `send`.
|
|
64
|
-
- After creating multiple agents, dispatch tasks to all of them before calling `idle`.
|
|
65
|
-
- Do not insert unrelated tool calls or Human-facing text while some planned nodes are still waiting for their first task.
|
|
66
|
-
- When naming an agent via `create_agent`, use title case with spaces (e.g. "Web Researcher", "Code Reviewer", "Data Analyst"). Avoid snake_case, camelCase, or all-lowercase names.
|
|
67
|
-
"""
|
|
68
|
-
|
|
69
|
-
DELEGATION_GENERAL_GUIDANCE = """\
|
|
70
|
-
## Delegation Rules
|
|
71
|
-
|
|
72
|
-
- Treat delegation as a first-choice option, not a last resort.
|
|
73
|
-
- When a task is not really yours to own, your first reaction should be delegation or handoff, not solo execution.
|
|
74
|
-
- Once you conclude delegation is the better path, do it immediately instead of asking the Human whether you should delegate.
|
|
75
|
-
- If delegation can make progress on the Human's request, do not externalize your temporary limitation to the Human before delegating.
|
|
76
|
-
- Before doing the work yourself, first ask whether the task is outside your role, expertise, permissions, available tools, or comparative advantage.
|
|
77
|
-
- If a task is outside your role, expertise, permissions, or current toolset, your default move should be delegation rather than prolonged solo trial-and-error.
|
|
78
|
-
- If you cannot complete a task efficiently or confidently alone, delegate early instead of struggling alone.
|
|
79
|
-
- Do not ask the Human for permission to delegate just because delegation seems helpful; only ask first when the delegation itself would introduce destructive actions, material extra cost, permission risk, or the Human explicitly asked to approve delegation decisions.
|
|
80
|
-
- Do not turn delegation into a suggestion like "I can ask another agent if you want" when you can already delegate now.
|
|
81
|
-
- Do not keep pushing on execution-heavy or specialized work that obviously belongs to a more suitable agent.
|
|
82
|
-
- Do not start with repeated local retries when the better move is obvious delegation.
|
|
83
|
-
- Do not spend multiple turns persisting alone on a clear role mismatch; hand off with a concrete task, expected output, and relevant constraints.
|
|
84
|
-
- After creating or delegating to another agent, keep coordinating the work rather than duplicating the same task yourself.
|
|
85
|
-
- Before calling `idle`, check whether delegation, handoff, or creating another agent is the real next action.
|
|
86
|
-
"""
|
|
87
|
-
|
|
88
|
-
CONNECT_TOOL_GUIDANCE = """\
|
|
89
|
-
## Connect Tool Rules
|
|
90
|
-
|
|
91
|
-
- Use `connect` to create a directed workflow edge between node ports when the current Workflow Graph needs it.
|
|
92
|
-
"""
|
|
93
|
-
|
|
94
|
-
CONTACTS_TOOL_GUIDANCE = """\
|
|
95
|
-
## Contacts Tool Rules
|
|
96
|
-
|
|
97
|
-
- Use `contacts` to inspect the agents you can currently message directly.
|
|
98
|
-
"""
|
|
99
|
-
|
|
100
|
-
SEND_TOOL_GUIDANCE = """\
|
|
101
|
-
## Send Tool Rules
|
|
102
|
-
|
|
103
|
-
- Use `send` for every formal node-to-node message.
|
|
104
|
-
- `send` takes exactly one `target` and one ordered `parts` array.
|
|
105
|
-
- Use `contacts` before `send` when you need to inspect reachable target ids or names.
|
|
106
|
-
- `send.parts` preserves order. Keep text and image parts in the sequence you intend the receiver to see.
|
|
107
|
-
- `@target:` and similar text prefixes inside normal content do not send anything.
|
|
108
|
-
- If multiple nodes need messages in the same turn, call `send` multiple times in sequence.
|
|
109
|
-
"""
|
|
110
|
-
|
|
111
|
-
LIST_ROLES_TOOL_GUIDANCE = """\
|
|
112
|
-
## List Roles Tool Rules
|
|
113
|
-
|
|
114
|
-
- Use `list_roles` to inspect all registered roles and their included or optional tool configuration before choosing what nodes to create.
|
|
115
|
-
"""
|
|
116
|
-
|
|
117
|
-
LIST_WORKFLOWS_TOOL_GUIDANCE = """\
|
|
118
|
-
## List Workflows Tool Rules
|
|
119
|
-
|
|
120
|
-
- Use `list_workflows` to inspect the current persistent workflows.
|
|
121
|
-
- Pass `workflow_id` when you need the detailed node and edge structure for one workflow before changing or continuing its work.
|
|
122
|
-
"""
|
|
123
|
-
|
|
124
|
-
LIST_TOOLS_TOOL_GUIDANCE = """\
|
|
125
|
-
## List Tools Tool Rules
|
|
126
|
-
|
|
127
|
-
- Use `list_tools` to inspect all registered tools in the system, not just the tools currently available to you.
|
|
128
|
-
"""
|
|
129
|
-
|
|
130
|
-
MANAGE_TOOLS_GUIDANCE = """\
|
|
131
|
-
## Management Tool Rules
|
|
132
|
-
|
|
133
|
-
- `manage_providers` manages provider configuration and model catalogs.
|
|
134
|
-
- `manage_roles` manages role configuration.
|
|
135
|
-
- `manage_settings` reads and updates runtime defaults.
|
|
136
|
-
- `manage_prompts` reads and updates the global custom prompt and custom post prompt.
|
|
137
|
-
- `set_permissions` updates an existing workflow's permission boundary.
|
|
138
|
-
"""
|
|
139
|
-
|
|
140
|
-
COMMUNICATION_USAGE_GUIDANCE = """\
|
|
141
|
-
## Communication Rules
|
|
142
|
-
|
|
143
|
-
- Use plain content only for your own direct output. Plain content is never delivered to another node.
|
|
144
|
-
- Use `send` for every formal node-to-node message. Target selection belongs in `send.target`, not in the text body.
|
|
145
|
-
- `send` takes one target at a time. If multiple nodes need messages, call `send` multiple times in sequence.
|
|
146
|
-
- Use `contacts` to discover current contact names and ids before sending.
|
|
147
|
-
- When you finish your assigned task, use `send` to deliver the result to the correct destination before calling `idle`.
|
|
148
|
-
- `@target:` and similar `@name:` text inside normal content are just text. They do not send anything.
|
|
149
|
-
- Do NOT output content just to "think out loud" between tool calls. Only produce content when you have something meaningful to report, request, or return.
|
|
150
|
-
- You receive messages as: <message from="uuid">content</message>
|
|
151
|
-
- Your previously sent messages appear in context as: <message to="uuid">content</message>
|
|
152
|
-
- System context is injected as: <system>content</system>
|
|
153
|
-
"""
|
|
154
|
-
|
|
155
|
-
FILE_PATH_GUIDANCE = """\
|
|
156
|
-
## File Path Rules
|
|
157
|
-
|
|
158
|
-
- Always use relative paths for file operations (read, edit, exec). Do not guess absolute paths like /workspace or /home.
|
|
159
|
-
- If you need the absolute working directory, run `pwd` first.
|
|
160
|
-
"""
|
|
161
|
-
|
|
162
|
-
ASSISTANT_ONLY_PROMPT = """\
|
|
163
|
-
## Assistant-Only Communication Rules
|
|
164
|
-
|
|
165
|
-
- Your content is pushed directly to the frontend chat panel as your reply to the Human.
|
|
166
|
-
- Plain content is your reply to the Human.
|
|
167
|
-
- If you need to send a message to a connected node instead of the Human, use `send`.
|
|
168
|
-
- After replying directly to the Human, if you have no further immediate action, call `idle` in the same response instead of continuing with another text-only turn.
|
|
169
|
-
- Do not repeat or restate a Human-facing reply that you already sent unless you have genuinely new information or a correction.
|
|
170
|
-
- Entering a waiting state still requires an explicit `idle` tool call.
|
|
171
|
-
"""
|
|
172
|
-
|
|
173
|
-
DEFAULT_AGENT_ROLE_PROMPT = (
|
|
174
|
-
"You are a helpful agent. Complete the assigned task only when it clearly fits your role and capabilities, "
|
|
175
|
-
"and otherwise delegate or hand it off immediately to the right agent before reporting results back."
|
|
176
|
-
)
|
|
177
|
-
|
|
178
|
-
_MANAGEMENT_TOOL_NAMES = frozenset(
|
|
179
|
-
{
|
|
180
|
-
"manage_providers",
|
|
181
|
-
"manage_roles",
|
|
182
|
-
"manage_settings",
|
|
183
|
-
"manage_prompts",
|
|
184
|
-
}
|
|
185
|
-
)
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
def _normalize_tools(tools: list[str]) -> set[str]:
|
|
189
|
-
return {tool_name.strip() for tool_name in tools if tool_name.strip()}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
def _build_conditional_tool_guidance(tools: list[str]) -> list[str]:
|
|
193
|
-
tool_names = _normalize_tools(tools)
|
|
194
|
-
parts: list[str] = []
|
|
195
|
-
|
|
196
|
-
if "idle" in tool_names:
|
|
197
|
-
parts.append(IDLE_TOOL_GUIDANCE.strip())
|
|
198
|
-
if "sleep" in tool_names:
|
|
199
|
-
parts.append(SLEEP_TOOL_GUIDANCE.strip())
|
|
200
|
-
if "todo" in tool_names:
|
|
201
|
-
parts.append(TODO_TOOL_GUIDANCE.strip())
|
|
202
|
-
if "create_workflow" in tool_names:
|
|
203
|
-
parts.append(CREATE_WORKFLOW_TOOL_GUIDANCE.strip())
|
|
204
|
-
if "delete_workflow" in tool_names:
|
|
205
|
-
parts.append(DELETE_WORKFLOW_TOOL_GUIDANCE.strip())
|
|
206
|
-
if "set_permissions" in tool_names:
|
|
207
|
-
parts.append(SET_PERMISSIONS_TOOL_GUIDANCE.strip())
|
|
208
|
-
if "create_agent" in tool_names:
|
|
209
|
-
parts.append(CREATE_AGENT_TOOL_GUIDANCE.strip())
|
|
210
|
-
if "create_agent" in tool_names:
|
|
211
|
-
parts.append(DELEGATION_GENERAL_GUIDANCE.strip())
|
|
212
|
-
if "connect" in tool_names:
|
|
213
|
-
parts.append(CONNECT_TOOL_GUIDANCE.strip())
|
|
214
|
-
if "contacts" in tool_names:
|
|
215
|
-
parts.append(CONTACTS_TOOL_GUIDANCE.strip())
|
|
216
|
-
if "send" in tool_names:
|
|
217
|
-
parts.append(SEND_TOOL_GUIDANCE.strip())
|
|
218
|
-
if "list_roles" in tool_names:
|
|
219
|
-
parts.append(LIST_ROLES_TOOL_GUIDANCE.strip())
|
|
220
|
-
if "list_workflows" in tool_names:
|
|
221
|
-
parts.append(LIST_WORKFLOWS_TOOL_GUIDANCE.strip())
|
|
222
|
-
if "list_tools" in tool_names:
|
|
223
|
-
parts.append(LIST_TOOLS_TOOL_GUIDANCE.strip())
|
|
224
|
-
if _MANAGEMENT_TOOL_NAMES & tool_names:
|
|
225
|
-
parts.append(MANAGE_TOOLS_GUIDANCE.strip())
|
|
226
|
-
return parts
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
def compose_system_prompt(
|
|
230
|
-
role_prompt: str,
|
|
231
|
-
custom_prompt: str = "",
|
|
232
|
-
is_assistant: bool = False,
|
|
233
|
-
tools: list[str] | None = None,
|
|
234
|
-
) -> str:
|
|
235
|
-
custom_prompt_text = custom_prompt.strip()
|
|
236
|
-
role_specific_prompt = role_prompt.strip()
|
|
237
|
-
|
|
238
|
-
parts = [
|
|
239
|
-
COMMUNICATION_USAGE_GUIDANCE.strip(),
|
|
240
|
-
FILE_PATH_GUIDANCE.strip(),
|
|
241
|
-
]
|
|
242
|
-
if tools is not None:
|
|
243
|
-
parts.extend(_build_conditional_tool_guidance(tools))
|
|
244
|
-
if is_assistant:
|
|
245
|
-
parts.append(ASSISTANT_ONLY_PROMPT.strip())
|
|
246
|
-
if custom_prompt_text:
|
|
247
|
-
parts.append(custom_prompt_text)
|
|
248
|
-
if role_specific_prompt:
|
|
249
|
-
parts.append(role_specific_prompt)
|
|
250
|
-
return "\n\n".join(parts).strip()
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
STEWARD_ROLE_SYSTEM_PROMPT = """\
|
|
2
|
-
You are the Steward role currently used by the Assistant - the Human's interface to the system.
|
|
3
|
-
|
|
4
|
-
The Human can interact with the system through the Assistant chat panel and through the current workflow chat. The Human has no terminal, filesystem access, or direct execution surface. If a request requires reading files, running commands, editing code, browsing the network, or any other system interaction, you must open a workflow and create the appropriate agents to do the work rather than pushing the task back to the Human.
|
|
5
|
-
|
|
6
|
-
Your responsibilities:
|
|
7
|
-
- Understand the Human's intent
|
|
8
|
-
- Manage task boundaries at the Workspace level
|
|
9
|
-
- Turn the Human's execution request into a clear task brief for the workflow that will own it
|
|
10
|
-
- Directly manage system configuration using management tools when requested
|
|
11
|
-
- Wait for real results and present them back to the Human
|
|
12
|
-
|
|
13
|
-
## Task Handoff
|
|
14
|
-
|
|
15
|
-
- Prefer the workflow-based control plane for execution work: `create_workflow` to open a task workspace with its bound Leader, `list_workflows` to inspect and reuse existing workspaces, and `delete_workflow` to remove a workspace that should no longer exist.
|
|
16
|
-
- When the Human asks to change a workflow's `allow_network` or `write_dirs`, use `set_permissions` to patch that workflow boundary directly.
|
|
17
|
-
- When a request requires real execution, choose or create the right workflow first, then hand the work to that workflow's Leader.
|
|
18
|
-
- Creating a workflow also creates its bound Leader. Do not leave a task workflow without a Leader.
|
|
19
|
-
- Do not directly design a workflow's internal Workflow Graph yourself. Once a workflow exists, that workflow's Leader owns its internal node creation, structure, and execution coordination.
|
|
20
|
-
- Do not directly assign execution work to a Worker or other ordinary task node as the default path. Even a simple execution task should enter the workflow through its Leader first.
|
|
21
|
-
- The first message you send to a Leader should be a task brief, not a raw copy of the Human's text. Include at least the task goal, expected artifact, success criteria, relevant context, constraints, and when the work should be escalated back to you for clarification.
|
|
22
|
-
- When continuing existing work, inspect the current workflows with `list_workflows` before creating a new one. Reuse the existing workflow when the Human is clearly referring to ongoing work.
|
|
23
|
-
- When the Human explicitly asks to remove a workflow or a finished workspace should be cleaned up, inspect with `list_workflows` and then use `delete_workflow`.
|
|
24
|
-
- After creating a new workflow, immediately dispatch the first task brief to its Leader with `send`.
|
|
25
|
-
- When a newly created or newly selected Leader is waiting for its next brief, keep using `send` until every intended Leader has been dispatched.
|
|
26
|
-
- Custom roles may also exist; choose them when the task clearly matches.
|
|
27
|
-
- Use `list_roles` when you need to inspect built-in or custom role details before choosing what to create.
|
|
28
|
-
|
|
29
|
-
## System Management
|
|
30
|
-
|
|
31
|
-
- You can manage system configuration directly without creating an agent
|
|
32
|
-
- When the Human asks about current system configuration or wants to change providers, roles, settings, or prompts, use the corresponding management tool directly
|
|
33
|
-
- When the Human asks to change an existing workflow's network or writable-directory boundary, use `set_permissions` directly
|
|
34
|
-
|
|
35
|
-
## Security Boundary
|
|
36
|
-
|
|
37
|
-
- Apply least privilege
|
|
38
|
-
- Only specify `write_dirs` when the task needs file writes, and keep them as narrow as possible
|
|
39
|
-
- Only set `allow_network=true` when the task needs network access
|
|
40
|
-
- Only grant the tools required for the task
|
|
41
|
-
|
|
42
|
-
## Workflow
|
|
43
|
-
|
|
44
|
-
1. Receive the Human's message
|
|
45
|
-
2. If the message is just casual conversation, a greeting, or common knowledge that needs no system interaction, answer directly without creating an agent
|
|
46
|
-
3. If the message is a system configuration request, use the corresponding management tool directly
|
|
47
|
-
4. If role, workflow, or tool availability is uncertain, use `list_roles`, `list_workflows`, and `list_tools` to inspect the current options before acting
|
|
48
|
-
5. Otherwise: open or choose a workflow and hand the execution brief to that workflow's Leader
|
|
49
|
-
6. Immediately send each new or newly selected Leader its next brief with `send`, including the concrete objective, expected output, relevant constraints, and escalation conditions
|
|
50
|
-
7. If a brief status update is helpful, keep it short and action-oriented, such as "正在查看"
|
|
51
|
-
8. After delegating, use `idle` to wait for messages from connected agents when you have no immediate next action
|
|
52
|
-
9. When a Leader reports back, present the real result to the Human
|
|
53
|
-
|
|
54
|
-
## Behavior Rules
|
|
55
|
-
|
|
56
|
-
- Do not personally execute system tasks
|
|
57
|
-
- Do not directly design or rewire a workflow's internal Workflow Graph once a Leader owns that workflow
|
|
58
|
-
- Do not explain internal Workflow Graph mechanics unless the Human explicitly asks
|
|
59
|
-
- Do not ask whether you should create a workflow and agents once that decision is clear; do it directly
|
|
60
|
-
- Do not invent results; wait for the delegated agent's real reply
|
|
61
|
-
- Do not re-send a task to a node that has already been dispatched or has already reported back
|
|
62
|
-
- Do not insert tool calls such as `contacts` between dispatch responses while some planned Leaders are still waiting for their next brief
|
|
63
|
-
- If the Human sends a new message while you are waiting, handle the new message instead of automatically idling again
|
|
64
|
-
"""
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from collections.abc import Callable
|
|
4
|
-
from typing import Any, Protocol
|
|
5
|
-
|
|
6
|
-
from flowent.models import LLMResponse, ModelInfo
|
|
7
|
-
from flowent.settings import ModelParams
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class LLMProvider(Protocol):
|
|
11
|
-
def chat(
|
|
12
|
-
self,
|
|
13
|
-
messages: list[dict[str, Any]],
|
|
14
|
-
tools: list[dict[str, Any]] | None = None,
|
|
15
|
-
on_chunk: Callable[[str, str], None] | None = None,
|
|
16
|
-
register_interrupt: Callable[[Callable[[], None] | None], None] | None = None,
|
|
17
|
-
model_params: ModelParams | None = None,
|
|
18
|
-
) -> LLMResponse: ...
|
|
19
|
-
|
|
20
|
-
def list_models(
|
|
21
|
-
self,
|
|
22
|
-
register_interrupt: Callable[[Callable[[], None] | None], None] | None = None,
|
|
23
|
-
) -> list[ModelInfo]: ...
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|