feat: access workflow internal API endpoints using compression
What does this merge request do and why?
feat: enable checkpoint data compression in workflow internal API endpoints. Workflow compression API reduces checkpoint size during transport
Previous MR created issues in uncompressed state due to not calling checkpoint_decoder, You can repeat them by commenting out object_hook=checkpoint_decoder in gitlab_workflow.py
feat: use workflows internal api with compression (!3621 - merged)
How to set up and validate locally
- Test duo workflow flows and agentic chats with compression support
- Test duo workflow flows and agentic chats without compression support
- On gitlab rails console (
bin/rails c) enable or disable the feature:
Feature.enable :duo_workflow_compress_checkpoint
Feature.enabled? :duo_workflow_compress_checkpoint
Feature.disable :duo_workflow_compress_checkpoint
- restart the services and vscode (probably not needed, but to be sure)
gdk restart rails-web duo-workflow-service gitlab-ai-gateway
- Check gitlab api log or duo workflow service log
tail -n 200 log/api_json.log | grep "/api/:version/ai/duo_workflows/workflows" | grep compress | jq
gdk tail duo-workflow-service
Dependencies
- API MR Allow compressed checkpoints in Duo workflows i... (gitlab-org/gitlab!209257 - merged)
- feature flag Add feature flag for Duo Workflow checkpoint co... (gitlab-org/gitlab!209299 - merged)
AttributeError: 'dict' object has no attribute 'type'
Traceback (most recent call last):
File "/home/aigateway/app/duo_workflow_service/workflows/abstract_workflow.py", line 282, in _compile_and_run_graph
async for type, state in compiled_graph.astream(
File "/home/aigateway/app/venv/ai-gateway-M6hW6iiC-py3.12/lib/python3.12/site-packages/langgraph/pregel/__init__.py", line 2652, in astream
while loop.tick(input_keys=self.input_channels):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/aigateway/app/venv/ai-gateway-M6hW6iiC-py3.12/lib/python3.12/site-packages/langgraph/pregel/loop.py", line 473, in tick
updated_channels = self._first(input_keys=input_keys)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/aigateway/app/venv/ai-gateway-M6hW6iiC-py3.12/lib/python3.12/site-packages/langgraph/pregel/loop.py", line 703, in _first
mv_writes, _ = apply_writes(
^^^^^^^^^^^^^
File "/home/aigateway/app/venv/ai-gateway-M6hW6iiC-py3.12/lib/python3.12/site-packages/langgraph/pregel/algo.py", line 305, in apply_writes
if channels[chan].update(vals) and get_next_version is not None:
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/aigateway/app/venv/ai-gateway-M6hW6iiC-py3.12/lib/python3.12/site-packages/langgraph/channels/binop.py", line 91, in update
self.value = self.operator(self.value, value)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/aigateway/app/duo_workflow_service/entities/state.py", line 244, in _conversation_history_reducer
current_msg_roles, current_msg_token = get_messages_profile(
^^^^^^^^^^^^^^^^^^^^^
File "/home/aigateway/app/duo_workflow_service/entities/state.py", line 218, in get_messages_profile
roles = [msg.type for msg in messages]
^^^^^^^^
AttributeError: 'dict' object has no attribute 'type'
{
"event": "'dict' object has no attribute 'type'",
"logger": "exceptions",
"level": "error",
"correlation_id": "848f8fec-722a-49ca-90b1-13f1d884d401",
"gitlab_global_user_id": "7hbE4xmTa2FltcIHykLtoyOYW0zYQ8kNILhSaz2kjlM=",
"workflow_id": "310",
"status_code": null,
"exception_class": "AttributeError",
"additional_details": {
"workflow_id": "310",
"source": "duo_workflow_service.checkpointer.gitlab_workflow"
},
"timestamp": "2025-11-05T17:30:36.139022Z",
"exception": "Traceback (most recent call last):\n File \"/home/aakgun/aakgun/1/gdk/gitlab-ai-gateway/duo_workflow_service/workflows/abstract_workflow.py\", line 289, in _compile_and_run_graph\n async for type, state in compiled_graph.astream(\n File \"/home/aakgun/aakgun/1/gdk/gitlab-ai-gateway/.venv/lib/python3.12/site-packages/langgraph/pregel/__init__.py\", line 2652, in astream\n while loop.tick(input_keys=self.input_channels):\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/aakgun/aakgun/1/gdk/gitlab-ai-gateway/.venv/lib/python3.12/site-packages/langgraph/pregel/loop.py\", line 473, in tick\n updated_channels = self._first(input_keys=input_keys)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/aakgun/aakgun/1/gdk/gitlab-ai-gateway/.venv/lib/python3.12/site-packages/langgraph/pregel/loop.py\", line 703, in _first\n mv_writes, _ = apply_writes(\n ^^^^^^^^^^^^^\n File \"/home/aakgun/aakgun/1/gdk/gitlab-ai-gateway/.venv/lib/python3.12/site-packages/langgraph/pregel/algo.py\", line 305, in apply_writes\n if channels[chan].update(vals) and get_next_version is not None:\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/aakgun/aakgun/1/gdk/gitlab-ai-gateway/.venv/lib/python3.12/site-packages/langgraph/channels/binop.py\", line 91, in update\n self.value = self.operator(self.value, value)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/aakgun/aakgun/1/gdk/gitlab-ai-gateway/duo_workflow_service/entities/state.py\", line 244, in _conversation_history_reducer\n current_msg_roles, current_msg_token = get_messages_profile(\n ^^^^^^^^^^^^^^^^^^^^^\n File \"/home/aakgun/aakgun/1/gdk/gitlab-ai-gateway/duo_workflow_service/entities/state.py\", line 218, in get_messages_profile\n roles = [msg.type for msg in messages]\n ^^^^^^^^\nAttributeError: 'dict' object has no attribute 'type'"
}
Merge request checklist
-
Tests added for new functionality. If not, please raise an issue to follow up. -
Documentation added/updated, if needed. -
If this change requires executor implementation: verified that issues/MRs exist for both Go executor and Node executor or confirmed that changes are backward-compatible and don't break existing executor functionality.
Edited by Alper Akgun