flowcept 0.9.2__tar.gz → 0.9.4__tar.gz
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.
- {flowcept-0.9.2 → flowcept-0.9.4}/PKG-INFO +4 -1
- {flowcept-0.9.2 → flowcept-0.9.4}/docs/api-reference.rst +52 -24
- {flowcept-0.9.2 → flowcept-0.9.4}/docs/architecture.rst +1 -1
- {flowcept-0.9.2 → flowcept-0.9.4}/docs/prov_capture.rst +9 -3
- {flowcept-0.9.2 → flowcept-0.9.4}/docs/prov_storage.rst +6 -0
- flowcept-0.9.4/examples/convergence_loop_example.py +44 -0
- flowcept-0.9.4/examples/instrumented_loop_example.py +77 -0
- flowcept-0.9.4/examples/mqtt_example.py +101 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/pyproject.toml +1 -1
- {flowcept-0.9.2 → flowcept-0.9.4}/resources/sample_settings.yaml +1 -1
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/flowcept_ctx_manager.py +12 -6
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/gui/gui_utils.py +52 -1
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/prompts/general_prompts.py +3 -2
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/prompts/in_memory_query_prompts.py +46 -18
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/tools/general_tools.py +16 -1
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/tools/in_memory_queries/in_memory_queries_tools.py +24 -7
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/tools/in_memory_queries/pandas_agent_utils.py +1 -1
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/task_data_preprocess.py +8 -2
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowcept_api/flowcept_controller.py +1 -1
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/instrumentation/flowcept_loop.py +91 -20
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/version.py +1 -1
- flowcept-0.9.2/examples/instrumented_loop_example.py +0 -19
- {flowcept-0.9.2 → flowcept-0.9.4}/.github/workflows/checks.yml +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/.github/workflows/create-release-n-publish.yml +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/.github/workflows/run-llm-tests.yml +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/.github/workflows/run-tests-all-dbs.yml +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/.github/workflows/run-tests-in-container.yml +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/.github/workflows/run-tests-kafka.yml +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/.github/workflows/run-tests-py313.yml +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/.github/workflows/run-tests-simple.yml +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/.github/workflows/run-tests.yml +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/.github/workflows/run_examples.sh +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/.github/workflows/version_bumper.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/.gitignore +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/.readthedocs.yaml +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/CONTRIBUTING.md +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/LICENSE +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/Makefile +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/README.md +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/deployment/Dockerfile +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/deployment/compose-grafana.yml +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/deployment/compose-kafka.yml +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/deployment/compose-mofka.yml +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/deployment/compose-mongo.yml +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/deployment/compose.yml +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/docs/cli-reference.rst +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/docs/conf.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/docs/contributing.rst +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/docs/img/architecture-diagram.png +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/docs/img/flowcept-logo-dark.png +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/docs/img/flowcept-logo.png +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/docs/index.rst +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/docs/quick_start.rst +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/docs/schemas.rst +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/docs/setup.rst +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/docs/task_schema.rst +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/docs/telemetry_capture.rst +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/docs/workflow_schema.rst +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/agents/a2a/README.md +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/agents/a2a/agent1.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/agents/a2a/agent2.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/agents/aec_agent_context_manager.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/agents/aec_agent_mock.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/agents/aec_prompts.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/agents/opt_driver_mock.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/consumers/ping_pong_example.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/consumers/simple_consumer.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/consumers/simple_publisher.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/dask_example.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/distributed_consumer_example.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/instrumented_simple_example.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/llm_complex/README.md +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/llm_complex/custom_provenance_id_mapping.yaml +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/llm_complex/llm_dataprep.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/llm_complex/llm_main_example.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/llm_complex/llm_model.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/llm_complex/llm_test_runner.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/mlflow_example.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/single_layer_perceptron_example.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/start_here.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/tensorboard_example.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/unmanaged/main.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/examples/unmanaged/simple_task.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/notebooks/analytics.ipynb +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/notebooks/dask.ipynb +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/notebooks/dask_from_CLI.ipynb +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/notebooks/mlflow.ipynb +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/notebooks/reset_dask_nb_exec_counts.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/notebooks/tensorboard.ipynb +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/resources/mofka/bedrock_setup.sh +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/resources/mofka/consumer.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/resources/mofka/mofka-requirements.yaml +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/resources/mofka/mofka_config.json +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/resources/simple_redis_consumer.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/agent_client.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/agents_utils.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/dynamic_schema_tracker.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/flowcept_agent.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/gui/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/gui/agent_gui.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/llms/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/llms/claude_gcp.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/llms/gemini25.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/prompts/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/tools/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/agents/tools/in_memory_queries/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/analytics/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/analytics/analytics_utils.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/analytics/data_augmentation.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/analytics/plot.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/cli.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/autoflush_buffer.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/daos/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/daos/docdb_dao/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/daos/docdb_dao/docdb_dao_base.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/daos/docdb_dao/lmdb_dao.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/daos/docdb_dao/mongodb_dao.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/daos/keyvalue_dao.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/daos/mq_dao/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/daos/mq_dao/mq_dao_base.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/daos/mq_dao/mq_dao_kafka.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/daos/mq_dao/mq_dao_mofka.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/daos/mq_dao/mq_dao_redis.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/daos/redis_conn.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/flowcept_dataclasses/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/flowcept_dataclasses/base_settings_dataclasses.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/flowcept_dataclasses/task_object.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/flowcept_dataclasses/telemetry.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/flowcept_dataclasses/workflow_object.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/flowcept_logger.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/query_utils.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/settings_factory.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/utils.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/commons/vocabulary.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/configs.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowcept_api/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowcept_api/db_api.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowcept_api/task_query_api.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowcept_webserver/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowcept_webserver/app.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowcept_webserver/resources/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowcept_webserver/resources/query_rsrc.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowcept_webserver/resources/task_messages_rsrc.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/adapters/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/adapters/base_interceptor.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/adapters/brokers/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/adapters/brokers/mqtt_interceptor.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/adapters/dask/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/adapters/dask/dask_dataclasses.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/adapters/dask/dask_interceptor.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/adapters/dask/dask_plugins.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/adapters/instrumentation_interceptor.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/adapters/interceptor_state_manager.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/adapters/mlflow/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/adapters/mlflow/interception_event_handler.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/adapters/mlflow/mlflow_dao.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/adapters/mlflow/mlflow_dataclasses.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/adapters/mlflow/mlflow_interceptor.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/adapters/tensorboard/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/adapters/tensorboard/tensorboard_dataclasses.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/adapters/tensorboard/tensorboard_interceptor.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/consumers/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/consumers/agent/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/consumers/agent/base_agent_context_manager.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/consumers/base_consumer.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/consumers/consumer_utils.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/consumers/document_inserter.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/flowceptor/telemetry_capture.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/instrumentation/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/instrumentation/flowcept_agent_task.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/instrumentation/flowcept_decorator.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/instrumentation/flowcept_task.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/instrumentation/flowcept_torch.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/src/flowcept/instrumentation/task_capture.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/adapters/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/adapters/dask_test_utils.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/adapters/test_broker.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/adapters/test_dask.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/adapters/test_dask_with_context_mgmt.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/adapters/test_file_observer.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/adapters/test_mlflow.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/adapters/test_tensorboard.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/api/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/api/db_api_test.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/api/flowcept_api_test.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/api/sample_data.json +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/api/sample_data_with_telemetry_and_rai.json +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/api/task_query_api_test.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/doc_db_inserter/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/doc_db_inserter/doc_db_inserter_test.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/instrumentation_tests/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/instrumentation_tests/flowcept_explicit_tasks.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/instrumentation_tests/flowcept_loop_test.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/instrumentation_tests/flowcept_task_decorator_test.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/instrumentation_tests/ml_tests/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/instrumentation_tests/ml_tests/dl_trainer.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/instrumentation_tests/ml_tests/ml_decorator_dask_test.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/instrumentation_tests/ml_tests/ml_decorator_test.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/misc_tests/__init__.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/misc_tests/log_test.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/misc_tests/singleton_test.py +0 -0
- {flowcept-0.9.2 → flowcept-0.9.4}/tests/misc_tests/telemetry_test.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flowcept
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.4
|
|
4
4
|
Summary: Capture and query workflow provenance data using data observability
|
|
5
5
|
Author: Oak Ridge National Laboratory
|
|
6
6
|
License-Expression: MIT
|
|
@@ -25,6 +25,7 @@ Requires-Dist: gitpython; extra == 'all'
|
|
|
25
25
|
Requires-Dist: google-genai; extra == 'all'
|
|
26
26
|
Requires-Dist: jupyterlab; extra == 'all'
|
|
27
27
|
Requires-Dist: langchain-community; extra == 'all'
|
|
28
|
+
Requires-Dist: langchain-openai; extra == 'all'
|
|
28
29
|
Requires-Dist: lmdb; extra == 'all'
|
|
29
30
|
Requires-Dist: mcp[cli]; extra == 'all'
|
|
30
31
|
Requires-Dist: mlflow-skinny; extra == 'all'
|
|
@@ -85,11 +86,13 @@ Provides-Extra: kafka
|
|
|
85
86
|
Requires-Dist: confluent-kafka<=2.8.0; extra == 'kafka'
|
|
86
87
|
Provides-Extra: llm-agent
|
|
87
88
|
Requires-Dist: langchain-community; extra == 'llm-agent'
|
|
89
|
+
Requires-Dist: langchain-openai; extra == 'llm-agent'
|
|
88
90
|
Requires-Dist: mcp[cli]; extra == 'llm-agent'
|
|
89
91
|
Requires-Dist: streamlit; extra == 'llm-agent'
|
|
90
92
|
Provides-Extra: llm-google
|
|
91
93
|
Requires-Dist: google-genai; extra == 'llm-google'
|
|
92
94
|
Requires-Dist: langchain-community; extra == 'llm-google'
|
|
95
|
+
Requires-Dist: langchain-openai; extra == 'llm-google'
|
|
93
96
|
Requires-Dist: mcp[cli]; extra == 'llm-google'
|
|
94
97
|
Requires-Dist: streamlit; extra == 'llm-google'
|
|
95
98
|
Provides-Extra: lmdb
|
|
@@ -1,37 +1,27 @@
|
|
|
1
1
|
API Reference
|
|
2
2
|
=============
|
|
3
3
|
|
|
4
|
-
..
|
|
5
|
-
:
|
|
6
|
-
:
|
|
4
|
+
.. autosummary::
|
|
5
|
+
:toctree: generated/
|
|
6
|
+
:recursive:
|
|
7
7
|
|
|
8
|
+
flowcept.Flowcept
|
|
9
|
+
flowcept.flowcept_api.db_api.DBAPI
|
|
10
|
+
flowcept.TaskObject
|
|
11
|
+
flowcept.WorkflowObject
|
|
12
|
+
flowcept.FlowceptTask
|
|
13
|
+
flowcept.FlowceptLoop
|
|
14
|
+
flowcept.FlowceptLightweightLoop
|
|
8
15
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Core components
|
|
12
|
-
---------------
|
|
16
|
+
Main Flowcept Object
|
|
17
|
+
--------------------
|
|
13
18
|
|
|
14
19
|
.. autoclass:: flowcept.Flowcept
|
|
15
20
|
:members:
|
|
21
|
+
:special-members: __init__
|
|
22
|
+
:exclude-members: __weakref__, __dict__, __module__
|
|
16
23
|
|
|
17
24
|
|
|
18
|
-
Main Message Objects
|
|
19
|
-
---------------------
|
|
20
|
-
|
|
21
|
-
.. autoclass:: flowcept.TaskObject
|
|
22
|
-
:members:
|
|
23
|
-
|
|
24
|
-
.. autoclass:: flowcept.WorkflowObject
|
|
25
|
-
:members:
|
|
26
|
-
|
|
27
|
-
FlowceptTask object
|
|
28
|
-
-------------------
|
|
29
|
-
|
|
30
|
-
.. autoclass:: flowcept.FlowceptTask
|
|
31
|
-
:members:
|
|
32
|
-
:special-members: __init__
|
|
33
|
-
:undoc-members:
|
|
34
|
-
:show-inheritance:
|
|
35
25
|
|
|
36
26
|
Flowcept.db: Querying the Database
|
|
37
27
|
----------------------------------
|
|
@@ -58,4 +48,42 @@ Typical usage:
|
|
|
58
48
|
.. autoclass:: flowcept.flowcept_api.db_api.DBAPI
|
|
59
49
|
:members:
|
|
60
50
|
:undoc-members:
|
|
51
|
+
:show-inheritance:
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
Main Message Objects
|
|
55
|
+
---------------------
|
|
56
|
+
|
|
57
|
+
.. autoclass:: flowcept.TaskObject
|
|
58
|
+
:members:
|
|
59
|
+
|
|
60
|
+
.. autoclass:: flowcept.WorkflowObject
|
|
61
|
+
:members:
|
|
62
|
+
|
|
63
|
+
FlowceptTask object
|
|
64
|
+
-------------------
|
|
65
|
+
|
|
66
|
+
.. autoclass:: flowcept.FlowceptTask
|
|
67
|
+
:members:
|
|
68
|
+
:special-members: __init__
|
|
69
|
+
:undoc-members:
|
|
70
|
+
:show-inheritance:
|
|
71
|
+
|
|
72
|
+
FlowceptLoop object
|
|
73
|
+
-------------------
|
|
74
|
+
|
|
75
|
+
.. autoclass:: flowcept.FlowceptLoop
|
|
76
|
+
:members:
|
|
77
|
+
:special-members: __init__
|
|
78
|
+
:undoc-members:
|
|
79
|
+
:show-inheritance:
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
FlowceptLightweightLoop object
|
|
83
|
+
------------------------------
|
|
84
|
+
|
|
85
|
+
.. autoclass:: flowcept.FlowceptLightweightLoop
|
|
86
|
+
:members:
|
|
87
|
+
:special-members: __init__
|
|
88
|
+
:undoc-members:
|
|
61
89
|
:show-inheritance:
|
|
@@ -25,6 +25,10 @@ Decorators
|
|
|
25
25
|
--------------------------
|
|
26
26
|
|
|
27
27
|
Use decorators to mark functions as **workflows** or **tasks** with almost no code changes.
|
|
28
|
+
If using the decorators, we expect that `instrumentation` is enabled in your settings file.
|
|
29
|
+
If it is not, the provenance capture will be simply ignored and the decorated function
|
|
30
|
+
will run as if without any Flowcept instrumentation.
|
|
31
|
+
|
|
28
32
|
|
|
29
33
|
``@flowcept`` (wrap a “main” function as a workflow)
|
|
30
34
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
@@ -431,18 +435,20 @@ Requires an active workflow (``with Flowcept(...)`` or ``Flowcept().start()``).
|
|
|
431
435
|
with Flowcept(workflow_name="custom_tasks"):
|
|
432
436
|
# Context-managed publish
|
|
433
437
|
with FlowceptTask(activity_id="download", used={"url": "https://..."}) as t:
|
|
434
|
-
data = b"..."
|
|
435
|
-
t.
|
|
438
|
+
data = b"..." # Some binary data
|
|
439
|
+
t.end(data=data, generated={"bytes": len(data)})
|
|
436
440
|
|
|
437
441
|
# Or publish explicitly
|
|
438
442
|
task = FlowceptTask(activity_id="parse", used={"bytes": len(data)})
|
|
439
|
-
task.
|
|
443
|
+
task.end({"records": 42})
|
|
440
444
|
task.send() # publishes to MQ
|
|
441
445
|
|
|
442
446
|
**Notes**:
|
|
443
447
|
|
|
444
448
|
- Use **context** (``with FlowceptTask(...)``) *or* call ``send()`` explicitly.
|
|
445
449
|
- Flows publish to the MQ; persistence/queries require a DB (e.g., MongoDB).
|
|
450
|
+
- See also: `Consumer example <https://flowcept.readthedocs.io/en/latest/prov_storage.html#example-extending-the-base-consumer>`_
|
|
451
|
+
- See also: `Ping pong example via PubSub with Flowcept <https://github.com/ORNL/flowcept/blob/main/examples/consumers/ping_pong_example.py>`_
|
|
446
452
|
|
|
447
453
|
References & Examples
|
|
448
454
|
---------------------
|
|
@@ -84,6 +84,12 @@ This can serve as a template for building custom provenance consumers.
|
|
|
84
84
|
consumer = MyConsumer()
|
|
85
85
|
consumer.start(daemon=False)
|
|
86
86
|
|
|
87
|
+
**Notes**:
|
|
88
|
+
|
|
89
|
+
- See also: `Explicit publish example <file:///Users/rsr/Documents/GDrive/ORNL/dev/flowcept/docs/_build/html/prov_capture.html#custom-task-creation-fully-customizable>`_
|
|
90
|
+
- See also: `Ping pong example via PubSub with Flowcept <https://github.com/ORNL/flowcept/blob/main/examples/consumers/ping_pong_example.py>`_
|
|
91
|
+
|
|
92
|
+
|
|
87
93
|
|
|
88
94
|
Document Inserter
|
|
89
95
|
-----------------
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from flowcept import Flowcept, FlowceptLoop
|
|
2
|
+
|
|
3
|
+
THRESHOLD = 0.05
|
|
4
|
+
MAX_ITERS = 50
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def update_error(e: float) -> float:
|
|
8
|
+
"""Dummy update rule that shrinks error each step."""
|
|
9
|
+
return e * 0.7 # replace with your real update
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def finalize_loop(loop):
|
|
13
|
+
"""Flush the last iteration so it’s captured even if we break early."""
|
|
14
|
+
if getattr(loop, "enabled", False) and getattr(loop, "_last_iteration_task", None) is not None:
|
|
15
|
+
try:
|
|
16
|
+
loop._end_iteration_task(loop._last_iteration_task) # uses FlowceptLoop internals
|
|
17
|
+
except Exception:
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# --- Convergence with FlowceptLoop ---
|
|
22
|
+
error = 1.0
|
|
23
|
+
loop = FlowceptLoop(
|
|
24
|
+
items=range(MAX_ITERS), # upper bound; we’ll break early on convergence
|
|
25
|
+
loop_name="convergence",
|
|
26
|
+
item_name="iter",
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
for it in loop:
|
|
30
|
+
# --- your loop body ---
|
|
31
|
+
error = update_error(error)
|
|
32
|
+
print(f"iter={it} error={error:.4f}")
|
|
33
|
+
|
|
34
|
+
# Record per-iteration outputs (only once per iteration)
|
|
35
|
+
loop.end_iter({
|
|
36
|
+
"iter": it,
|
|
37
|
+
"error": error,
|
|
38
|
+
"status": "converged" if error <= THRESHOLD else "continuing",
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
# Convergence check — emulate: while error > THRESHOLD: update error
|
|
42
|
+
if error <= THRESHOLD:
|
|
43
|
+
finalize_loop(loop) # ensure the last iteration is closed before breaking
|
|
44
|
+
break
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import random
|
|
2
|
+
from time import sleep
|
|
3
|
+
|
|
4
|
+
from flowcept import Flowcept, FlowceptLoop
|
|
5
|
+
|
|
6
|
+
# EXAMPLE 1:
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
iterations = range(1, 5)
|
|
10
|
+
|
|
11
|
+
with Flowcept():
|
|
12
|
+
|
|
13
|
+
loop = FlowceptLoop(iterations) # See also: FlowceptLightweightLoop
|
|
14
|
+
for item in loop:
|
|
15
|
+
loss = random.random()
|
|
16
|
+
sleep(0.05)
|
|
17
|
+
print(item, loss)
|
|
18
|
+
# The following is optional, in case you want to capture values generated inside the loop.
|
|
19
|
+
loop.end_iter({"item": item, "loss": loss})
|
|
20
|
+
|
|
21
|
+
docs = Flowcept.db.get_tasks_from_current_workflow()
|
|
22
|
+
assert len(docs) == len(iterations)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# EXAMPLE 2: WHILE LOOP EXAMPLE
|
|
26
|
+
# The following code is equivalent to:
|
|
27
|
+
# while layer_for_control_update <= num_layers - 1:
|
|
28
|
+
# ... loop code ...
|
|
29
|
+
# layer_for_control_update += 1
|
|
30
|
+
|
|
31
|
+
layer_for_control_update = 2
|
|
32
|
+
num_layers = 6
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def do_work(layer_ix: int) -> dict:
|
|
36
|
+
"""Dummy per-iteration work that returns something to log."""
|
|
37
|
+
# simulate some computation
|
|
38
|
+
value = layer_ix * 10
|
|
39
|
+
return {"value": value}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# Wrap the loop with FlowceptLoop
|
|
43
|
+
iterations = range(layer_for_control_update, num_layers)
|
|
44
|
+
|
|
45
|
+
# You can create with_flowcept flags
|
|
46
|
+
with_flowcept = True
|
|
47
|
+
|
|
48
|
+
if with_flowcept:
|
|
49
|
+
loop = FlowceptLoop(
|
|
50
|
+
items=iterations,
|
|
51
|
+
loop_name="control_loop",
|
|
52
|
+
item_name="layer_ix",
|
|
53
|
+
# parent_task_id="optional-parent-id",
|
|
54
|
+
# workflow_id="optional-workflow-id",
|
|
55
|
+
)
|
|
56
|
+
iterations = loop
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
for layer_ix in iterations:
|
|
60
|
+
# Your loop body
|
|
61
|
+
result = do_work(layer_ix)
|
|
62
|
+
print(f"Processed layer {layer_ix}, result={result}")
|
|
63
|
+
|
|
64
|
+
if with_flowcept:
|
|
65
|
+
# Record per-iteration outputs
|
|
66
|
+
iterations.end_iter({
|
|
67
|
+
"layer_ix": layer_ix,
|
|
68
|
+
"status": "updated",
|
|
69
|
+
**result, # attach any metrics you computed
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
if with_flowcept:
|
|
73
|
+
docs = Flowcept.db.get_tasks_from_current_workflow()
|
|
74
|
+
assert len(docs) == len(iterations)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# EXAMPLE 3: WHILE LOOP EXAMPLE
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# broker_minimal_example.py
|
|
2
|
+
import json
|
|
3
|
+
import time
|
|
4
|
+
import uuid
|
|
5
|
+
import paho.mqtt.client as mqtt
|
|
6
|
+
|
|
7
|
+
from flowcept import Flowcept
|
|
8
|
+
from flowcept.configs import settings
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def configure_flowcept_for_mqtt():
|
|
12
|
+
"""
|
|
13
|
+
Mirror your settings.yaml exactly under adapters.broker_mqtt so the
|
|
14
|
+
MQTTBrokerInterceptor picks it up via self.settings.
|
|
15
|
+
"""
|
|
16
|
+
settings.setdefault("adapters", {})
|
|
17
|
+
settings["adapters"]["broker_mqtt"] = {
|
|
18
|
+
"kind": "broker",
|
|
19
|
+
"host": "localhost",
|
|
20
|
+
"port": 30011,
|
|
21
|
+
"protocol": "mqtt3.1.1",
|
|
22
|
+
"queues": ["#"],
|
|
23
|
+
"username": "postman",
|
|
24
|
+
"password": "p",
|
|
25
|
+
"qos": 2,
|
|
26
|
+
"task_subtype": "intersect_msg",
|
|
27
|
+
"tracked_keys": {
|
|
28
|
+
"used": "payload",
|
|
29
|
+
"generated": None, # ~ in YAML
|
|
30
|
+
"custom_metadata": ["headers", "msgId"],
|
|
31
|
+
"activity_id": "operationId",
|
|
32
|
+
"submitted_at": None,
|
|
33
|
+
"started_at": None,
|
|
34
|
+
"ended_at": None,
|
|
35
|
+
"registered_at": None,
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def publish_one_message(
|
|
41
|
+
host="localhost",
|
|
42
|
+
port=30011,
|
|
43
|
+
username="postman",
|
|
44
|
+
password="p",
|
|
45
|
+
topic="flowcept/demo/test",
|
|
46
|
+
):
|
|
47
|
+
"""
|
|
48
|
+
Publish a single JSON payload with the fields your tracked_keys expect:
|
|
49
|
+
- payload -> mapped to Task.used
|
|
50
|
+
- headers, msgId -> copied into Task.custom_metadata
|
|
51
|
+
- operationId -> mapped to Task.activity_id
|
|
52
|
+
"""
|
|
53
|
+
client = mqtt.Client(protocol=mqtt.MQTTv311)
|
|
54
|
+
client.username_pw_set(username, password)
|
|
55
|
+
client.connect(host, port, keepalive=60)
|
|
56
|
+
|
|
57
|
+
payload = {
|
|
58
|
+
"payload": {"greeting": "hello from mqtt"}, # becomes Task.used
|
|
59
|
+
"headers": {"x-source": "unit-test", "x-env": "local"},
|
|
60
|
+
"msgId": str(uuid.uuid4()),
|
|
61
|
+
"operationId": "op-xyz-123", # becomes Task.activity_id
|
|
62
|
+
# optional extras also okay
|
|
63
|
+
"status": "FINISHED",
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
client.publish(topic, json.dumps(payload), qos=2, retain=False)
|
|
67
|
+
client.disconnect()
|
|
68
|
+
return payload
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def main():
|
|
72
|
+
# 1) Apply settings that match your YAML
|
|
73
|
+
configure_flowcept_for_mqtt()
|
|
74
|
+
|
|
75
|
+
# 2) Start Flowcept in context for the broker_mqtt adapter
|
|
76
|
+
with Flowcept("broker_mqtt"):
|
|
77
|
+
# 3) Start the interceptor (runs MQTT loop in a background thread)
|
|
78
|
+
# Give it a moment to connect/subscribe to "#"
|
|
79
|
+
time.sleep(1.0)
|
|
80
|
+
|
|
81
|
+
# 4) Publish one message
|
|
82
|
+
sent = publish_one_message()
|
|
83
|
+
print("Published:", sent)
|
|
84
|
+
|
|
85
|
+
# 5) Allow time for ingest
|
|
86
|
+
time.sleep(2.0)
|
|
87
|
+
|
|
88
|
+
# 6) (Optional) Query Flowcept DB for the ingested task
|
|
89
|
+
try:
|
|
90
|
+
# Query by nested field in used (payload.greeting)
|
|
91
|
+
tasks = Flowcept.db.query(filter={"used.greeting": "hello from mqtt"})
|
|
92
|
+
if tasks:
|
|
93
|
+
print("Ingested task example:\n", json.dumps(tasks[0], indent=2))
|
|
94
|
+
else:
|
|
95
|
+
print("No tasks found for filter used.greeting == 'hello from mqtt'")
|
|
96
|
+
except Exception as e:
|
|
97
|
+
print(f"DB query failed/skipped: {e}")
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
if __name__ == "__main__":
|
|
101
|
+
main()
|
|
@@ -65,7 +65,7 @@ mlflow = ["mlflow-skinny", "SQLAlchemy", "alembic", "watchdog", "cryptography"]
|
|
|
65
65
|
nvidia = ["nvidia-ml-py"]
|
|
66
66
|
mqtt = ["paho-mqtt"]
|
|
67
67
|
tensorboard = ["tensorboard", "tensorflow", "tbparse"]
|
|
68
|
-
llm_agent = ["mcp[cli]", "langchain_community", "streamlit"]
|
|
68
|
+
llm_agent = ["mcp[cli]", "langchain_community", "streamlit", "langchain_openai"]
|
|
69
69
|
llm_google = ["flowcept[llm_agent]", "google-genai"]
|
|
70
70
|
|
|
71
71
|
dev = [
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
flowcept_version: 0.9.
|
|
1
|
+
flowcept_version: 0.9.4 # Version of the Flowcept package. This setting file is compatible with this version.
|
|
2
2
|
|
|
3
3
|
project:
|
|
4
4
|
debug: true # Toggle debug mode. This will add a property `debug: true` to all saved data, making it easier to retrieve/delete them later.
|
|
@@ -37,6 +37,7 @@ class FlowceptAppContext(BaseAppContext):
|
|
|
37
37
|
tasks_schema: Dict | None # TODO: we dont need to keep the tasks_schema in context, just in the manager's memory.
|
|
38
38
|
value_examples: Dict | None
|
|
39
39
|
tracker_config: Dict | None
|
|
40
|
+
custom_guidance: List[str] | None
|
|
40
41
|
|
|
41
42
|
|
|
42
43
|
class FlowceptAgentContextManager(BaseAgentContextManager):
|
|
@@ -53,7 +54,7 @@ class FlowceptAgentContextManager(BaseAgentContextManager):
|
|
|
53
54
|
Current application context holding task state and QA components.
|
|
54
55
|
msgs_counter : int
|
|
55
56
|
Counter tracking how many task messages have been processed.
|
|
56
|
-
|
|
57
|
+
context_chunk_size : int
|
|
57
58
|
Number of task messages to collect before triggering QA index building and LLM analysis.
|
|
58
59
|
qa_manager : FlowceptQAManager
|
|
59
60
|
Utility for constructing QA chains from task summaries.
|
|
@@ -64,7 +65,7 @@ class FlowceptAgentContextManager(BaseAgentContextManager):
|
|
|
64
65
|
self.tracker_config = dict(max_examples=3, max_str_len=50)
|
|
65
66
|
self.schema_tracker = DynamicSchemaTracker(**self.tracker_config)
|
|
66
67
|
self.msgs_counter = 0
|
|
67
|
-
self.
|
|
68
|
+
self.context_chunk_size = 1 # Should be in the settings
|
|
68
69
|
super().__init__()
|
|
69
70
|
|
|
70
71
|
def message_handler(self, msg_obj: Dict):
|
|
@@ -98,18 +99,22 @@ class FlowceptAgentContextManager(BaseAgentContextManager):
|
|
|
98
99
|
if len(task_summary.get("tags", [])):
|
|
99
100
|
self.context.critical_tasks.append(task_summary)
|
|
100
101
|
|
|
101
|
-
if self.msgs_counter > 0 and self.msgs_counter % self.
|
|
102
|
+
if self.msgs_counter > 0 and self.msgs_counter % self.context_chunk_size == 0:
|
|
102
103
|
self.logger.debug(
|
|
103
|
-
f"Going to add to index! {(self.msgs_counter - self.
|
|
104
|
+
f"Going to add to index! {(self.msgs_counter - self.context_chunk_size, self.msgs_counter)}"
|
|
104
105
|
)
|
|
105
106
|
try:
|
|
106
107
|
self.update_schema_and_add_to_df(
|
|
107
|
-
tasks=self.context.task_summaries[
|
|
108
|
+
tasks=self.context.task_summaries[
|
|
109
|
+
self.msgs_counter - self.context_chunk_size : self.msgs_counter
|
|
110
|
+
]
|
|
108
111
|
)
|
|
109
112
|
except Exception as e:
|
|
110
113
|
self.logger.error(
|
|
111
114
|
f"Could not add these tasks to buffer!\n"
|
|
112
|
-
f"{
|
|
115
|
+
f"{
|
|
116
|
+
self.context.task_summaries[self.msgs_counter - self.context_chunk_size : self.msgs_counter]
|
|
117
|
+
}"
|
|
113
118
|
)
|
|
114
119
|
self.logger.exception(e)
|
|
115
120
|
|
|
@@ -152,6 +157,7 @@ class FlowceptAgentContextManager(BaseAgentContextManager):
|
|
|
152
157
|
df=pd.DataFrame(),
|
|
153
158
|
tasks_schema={},
|
|
154
159
|
value_examples={},
|
|
160
|
+
custom_guidance=[],
|
|
155
161
|
tracker_config=self.tracker_config,
|
|
156
162
|
)
|
|
157
163
|
DEBUG = True # TODO debugging!
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import ast
|
|
1
3
|
import io
|
|
2
4
|
import json
|
|
3
5
|
|
|
@@ -122,6 +124,53 @@ def display_ai_msg_from_tool(tool_result: ToolResult):
|
|
|
122
124
|
return agent_reply
|
|
123
125
|
|
|
124
126
|
|
|
127
|
+
def _sniff_mime(b: bytes) -> str:
|
|
128
|
+
if b.startswith(b"\x89PNG\r\n\x1a\n"):
|
|
129
|
+
return "image/png"
|
|
130
|
+
if b.startswith(b"\xff\xd8\xff"):
|
|
131
|
+
return "image/jpeg"
|
|
132
|
+
if b.startswith(b"GIF87a") or b.startswith(b"GIF89a"):
|
|
133
|
+
return "image/gif"
|
|
134
|
+
if b.startswith(b"BM"):
|
|
135
|
+
return "image/bmp"
|
|
136
|
+
if b.startswith(b"RIFF") and b[8:12] == b"WEBP":
|
|
137
|
+
return "image/webp"
|
|
138
|
+
return "application/octet-stream"
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def ensure_data_uri(val):
|
|
142
|
+
r"""Accepts bytes/bytearray/memoryview or a repr like \"b'\\x89PNG...'\" and returns a data URL."""
|
|
143
|
+
if isinstance(val, str) and val.startswith("data:"):
|
|
144
|
+
return val
|
|
145
|
+
if isinstance(val, str) and val.startswith("b'"):
|
|
146
|
+
try:
|
|
147
|
+
val = ast.literal_eval(val) # turn repr into bytes
|
|
148
|
+
except Exception:
|
|
149
|
+
return None
|
|
150
|
+
if isinstance(val, memoryview):
|
|
151
|
+
val = val.tobytes()
|
|
152
|
+
if isinstance(val, bytearray):
|
|
153
|
+
val = bytes(val)
|
|
154
|
+
if isinstance(val, bytes):
|
|
155
|
+
mime = _sniff_mime(val)
|
|
156
|
+
return f"data:{mime};base64,{base64.b64encode(val).decode('ascii')}"
|
|
157
|
+
return val # path/URL, etc.
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def _render_df(df: pd.DataFrame, image_width: int = 90, row_height: int = 90):
|
|
161
|
+
if "image" in df.columns:
|
|
162
|
+
df = df.copy()
|
|
163
|
+
df["image"] = df["image"].apply(ensure_data_uri)
|
|
164
|
+
st.dataframe(
|
|
165
|
+
df,
|
|
166
|
+
column_config={"image": st.column_config.ImageColumn("Preview", width=image_width)},
|
|
167
|
+
hide_index=True,
|
|
168
|
+
row_height=row_height, # make thumbnails visible
|
|
169
|
+
)
|
|
170
|
+
else:
|
|
171
|
+
st.dataframe(df, hide_index=True)
|
|
172
|
+
|
|
173
|
+
|
|
125
174
|
def display_df_tool_response(tool_result: ToolResult):
|
|
126
175
|
r"""
|
|
127
176
|
Display the DataFrame contained in a ToolResult.
|
|
@@ -170,7 +219,8 @@ def display_df_tool_response(tool_result: ToolResult):
|
|
|
170
219
|
df = pd.read_csv(io.StringIO(result_df_str))
|
|
171
220
|
print("The result is a df")
|
|
172
221
|
if not df.empty:
|
|
173
|
-
|
|
222
|
+
_render_df(df)
|
|
223
|
+
|
|
174
224
|
print("Columns", str(df.columns))
|
|
175
225
|
print("Number of columns", len(df.columns))
|
|
176
226
|
else:
|
|
@@ -190,6 +240,7 @@ def display_df_tool_response(tool_result: ToolResult):
|
|
|
190
240
|
|
|
191
241
|
if summary:
|
|
192
242
|
st.markdown("📝 Summary:")
|
|
243
|
+
print(f"THIS IS THE SUMMARY\n{summary}")
|
|
193
244
|
st.markdown(summary)
|
|
194
245
|
elif summary_error:
|
|
195
246
|
st.markdown(f"⚠️ Encountered this error when summarizing the result dataframe:\n```text\n{summary_error}")
|
|
@@ -24,8 +24,9 @@ ROUTING_PROMPT = (
|
|
|
24
24
|
"Given the following user message, classify it into one of the following routes:\n"
|
|
25
25
|
"- small_talk: if it's casual conversation or some random word (e.g., 'hausdn', 'a', hello, how are you, what can you do, what's your name)\n"
|
|
26
26
|
"- plot: if user is requesting plots (e.g., plot, chart, visualize)\n"
|
|
27
|
-
"- in_context_query: if the user asks questions about tasks or data in running workflow (or a workflow that ran recently) or if the user mentions the in-memory 'df' or a dataframe.\n"
|
|
28
|
-
"-
|
|
27
|
+
#"- in_context_query: if the user asks questions about tasks or data in running workflow (or a workflow that ran recently) or if the user mentions the in-memory 'df' or a dataframe.\n"
|
|
28
|
+
"- in_context_query: if the user is querying the provenance data questions about tasks or data in running workflow (or a workflow that ran recently) or if the user mentions the in-memory 'df' or a dataframe.\n"
|
|
29
|
+
#"- historical_prov_query: if the user wants to query historical provenance data\n"
|
|
29
30
|
"- in_chat_query: if the user appears to be asking about something that has said recently in this chat.\n"
|
|
30
31
|
"- unknown: if you don't know.\n"
|
|
31
32
|
"Respond with only the route label."
|