fix(workflow_run): sequence_number race. (#21228)
Signed-off-by: -LAN- <laipz8200@outlook.com>
This commit is contained in:
parent
8f64327d57
commit
6b1ad634f1
@ -6,7 +6,7 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
from typing import Optional, Union
|
from typing import Optional, Union
|
||||||
|
|
||||||
from sqlalchemy import func, select
|
from sqlalchemy import select
|
||||||
from sqlalchemy.engine import Engine
|
from sqlalchemy.engine import Engine
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
|
||||||
@ -146,20 +146,7 @@ class SQLAlchemyWorkflowExecutionRepository(WorkflowExecutionRepository):
|
|||||||
db_model.workflow_id = domain_model.workflow_id
|
db_model.workflow_id = domain_model.workflow_id
|
||||||
db_model.triggered_from = self._triggered_from
|
db_model.triggered_from = self._triggered_from
|
||||||
|
|
||||||
# Check if this is a new record
|
# No sequence number generation needed anymore
|
||||||
with self._session_factory() as session:
|
|
||||||
existing = session.scalar(select(WorkflowRun).where(WorkflowRun.id == domain_model.id_))
|
|
||||||
if not existing:
|
|
||||||
# For new records, get the next sequence number
|
|
||||||
stmt = select(func.max(WorkflowRun.sequence_number)).where(
|
|
||||||
WorkflowRun.app_id == self._app_id,
|
|
||||||
WorkflowRun.tenant_id == self._tenant_id,
|
|
||||||
)
|
|
||||||
max_sequence = session.scalar(stmt)
|
|
||||||
db_model.sequence_number = (max_sequence or 0) + 1
|
|
||||||
else:
|
|
||||||
# For updates, keep the existing sequence number
|
|
||||||
db_model.sequence_number = existing.sequence_number
|
|
||||||
|
|
||||||
db_model.type = domain_model.workflow_type
|
db_model.type = domain_model.workflow_type
|
||||||
db_model.version = domain_model.workflow_version
|
db_model.version = domain_model.workflow_version
|
||||||
|
|||||||
@ -19,7 +19,6 @@ workflow_run_for_log_fields = {
|
|||||||
|
|
||||||
workflow_run_for_list_fields = {
|
workflow_run_for_list_fields = {
|
||||||
"id": fields.String,
|
"id": fields.String,
|
||||||
"sequence_number": fields.Integer,
|
|
||||||
"version": fields.String,
|
"version": fields.String,
|
||||||
"status": fields.String,
|
"status": fields.String,
|
||||||
"elapsed_time": fields.Float,
|
"elapsed_time": fields.Float,
|
||||||
@ -36,7 +35,6 @@ advanced_chat_workflow_run_for_list_fields = {
|
|||||||
"id": fields.String,
|
"id": fields.String,
|
||||||
"conversation_id": fields.String,
|
"conversation_id": fields.String,
|
||||||
"message_id": fields.String,
|
"message_id": fields.String,
|
||||||
"sequence_number": fields.Integer,
|
|
||||||
"version": fields.String,
|
"version": fields.String,
|
||||||
"status": fields.String,
|
"status": fields.String,
|
||||||
"elapsed_time": fields.Float,
|
"elapsed_time": fields.Float,
|
||||||
@ -63,7 +61,6 @@ workflow_run_pagination_fields = {
|
|||||||
|
|
||||||
workflow_run_detail_fields = {
|
workflow_run_detail_fields = {
|
||||||
"id": fields.String,
|
"id": fields.String,
|
||||||
"sequence_number": fields.Integer,
|
|
||||||
"version": fields.String,
|
"version": fields.String,
|
||||||
"graph": fields.Raw(attribute="graph_dict"),
|
"graph": fields.Raw(attribute="graph_dict"),
|
||||||
"inputs": fields.Raw(attribute="inputs_dict"),
|
"inputs": fields.Raw(attribute="inputs_dict"),
|
||||||
|
|||||||
@ -0,0 +1,66 @@
|
|||||||
|
"""remove sequence_number from workflow_runs
|
||||||
|
|
||||||
|
Revision ID: 0ab65e1cc7fa
|
||||||
|
Revises: 4474872b0ee6
|
||||||
|
Create Date: 2025-06-19 16:33:13.377215
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import models as models
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '0ab65e1cc7fa'
|
||||||
|
down_revision = '4474872b0ee6'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('workflow_runs', schema=None) as batch_op:
|
||||||
|
batch_op.drop_index(batch_op.f('workflow_run_tenant_app_sequence_idx'))
|
||||||
|
batch_op.drop_column('sequence_number')
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
|
||||||
|
# WARNING: This downgrade CANNOT recover the original sequence_number values!
|
||||||
|
# The original sequence numbers are permanently lost after the upgrade.
|
||||||
|
# This downgrade will regenerate sequence numbers based on created_at order,
|
||||||
|
# which may result in different values than the original sequence numbers.
|
||||||
|
#
|
||||||
|
# If you need to preserve original sequence numbers, use the alternative
|
||||||
|
# migration approach that creates a backup table before removal.
|
||||||
|
|
||||||
|
# Step 1: Add sequence_number column as nullable first
|
||||||
|
with op.batch_alter_table('workflow_runs', schema=None) as batch_op:
|
||||||
|
batch_op.add_column(sa.Column('sequence_number', sa.INTEGER(), autoincrement=False, nullable=True))
|
||||||
|
|
||||||
|
# Step 2: Populate sequence_number values based on created_at order within each app
|
||||||
|
# NOTE: This recreates sequence numbering logic but values will be different
|
||||||
|
# from the original sequence numbers that were removed in the upgrade
|
||||||
|
connection = op.get_bind()
|
||||||
|
connection.execute(sa.text("""
|
||||||
|
UPDATE workflow_runs
|
||||||
|
SET sequence_number = subquery.row_num
|
||||||
|
FROM (
|
||||||
|
SELECT id, ROW_NUMBER() OVER (
|
||||||
|
PARTITION BY tenant_id, app_id
|
||||||
|
ORDER BY created_at, id
|
||||||
|
) as row_num
|
||||||
|
FROM workflow_runs
|
||||||
|
) subquery
|
||||||
|
WHERE workflow_runs.id = subquery.id
|
||||||
|
"""))
|
||||||
|
|
||||||
|
# Step 3: Make the column NOT NULL and add the index
|
||||||
|
with op.batch_alter_table('workflow_runs', schema=None) as batch_op:
|
||||||
|
batch_op.alter_column('sequence_number', nullable=False)
|
||||||
|
batch_op.create_index(batch_op.f('workflow_run_tenant_app_sequence_idx'), ['tenant_id', 'app_id', 'sequence_number'], unique=False)
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
@ -386,7 +386,7 @@ class WorkflowRun(Base):
|
|||||||
- id (uuid) Run ID
|
- id (uuid) Run ID
|
||||||
- tenant_id (uuid) Workspace ID
|
- tenant_id (uuid) Workspace ID
|
||||||
- app_id (uuid) App ID
|
- app_id (uuid) App ID
|
||||||
- sequence_number (int) Auto-increment sequence number, incremented within the App, starting from 1
|
|
||||||
- workflow_id (uuid) Workflow ID
|
- workflow_id (uuid) Workflow ID
|
||||||
- type (string) Workflow type
|
- type (string) Workflow type
|
||||||
- triggered_from (string) Trigger source
|
- triggered_from (string) Trigger source
|
||||||
@ -419,13 +419,12 @@ class WorkflowRun(Base):
|
|||||||
__table_args__ = (
|
__table_args__ = (
|
||||||
db.PrimaryKeyConstraint("id", name="workflow_run_pkey"),
|
db.PrimaryKeyConstraint("id", name="workflow_run_pkey"),
|
||||||
db.Index("workflow_run_triggerd_from_idx", "tenant_id", "app_id", "triggered_from"),
|
db.Index("workflow_run_triggerd_from_idx", "tenant_id", "app_id", "triggered_from"),
|
||||||
db.Index("workflow_run_tenant_app_sequence_idx", "tenant_id", "app_id", "sequence_number"),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
id: Mapped[str] = mapped_column(StringUUID, server_default=db.text("uuid_generate_v4()"))
|
id: Mapped[str] = mapped_column(StringUUID, server_default=db.text("uuid_generate_v4()"))
|
||||||
tenant_id: Mapped[str] = mapped_column(StringUUID)
|
tenant_id: Mapped[str] = mapped_column(StringUUID)
|
||||||
app_id: Mapped[str] = mapped_column(StringUUID)
|
app_id: Mapped[str] = mapped_column(StringUUID)
|
||||||
sequence_number: Mapped[int] = mapped_column()
|
|
||||||
workflow_id: Mapped[str] = mapped_column(StringUUID)
|
workflow_id: Mapped[str] = mapped_column(StringUUID)
|
||||||
type: Mapped[str] = mapped_column(db.String(255))
|
type: Mapped[str] = mapped_column(db.String(255))
|
||||||
triggered_from: Mapped[str] = mapped_column(db.String(255))
|
triggered_from: Mapped[str] = mapped_column(db.String(255))
|
||||||
@ -485,7 +484,6 @@ class WorkflowRun(Base):
|
|||||||
"id": self.id,
|
"id": self.id,
|
||||||
"tenant_id": self.tenant_id,
|
"tenant_id": self.tenant_id,
|
||||||
"app_id": self.app_id,
|
"app_id": self.app_id,
|
||||||
"sequence_number": self.sequence_number,
|
|
||||||
"workflow_id": self.workflow_id,
|
"workflow_id": self.workflow_id,
|
||||||
"type": self.type,
|
"type": self.type,
|
||||||
"triggered_from": self.triggered_from,
|
"triggered_from": self.triggered_from,
|
||||||
@ -511,7 +509,6 @@ class WorkflowRun(Base):
|
|||||||
id=data.get("id"),
|
id=data.get("id"),
|
||||||
tenant_id=data.get("tenant_id"),
|
tenant_id=data.get("tenant_id"),
|
||||||
app_id=data.get("app_id"),
|
app_id=data.get("app_id"),
|
||||||
sequence_number=data.get("sequence_number"),
|
|
||||||
workflow_id=data.get("workflow_id"),
|
workflow_id=data.get("workflow_id"),
|
||||||
type=data.get("type"),
|
type=data.get("type"),
|
||||||
triggered_from=data.get("triggered_from"),
|
triggered_from=data.get("triggered_from"),
|
||||||
|
|||||||
@ -163,7 +163,6 @@ def real_workflow_run():
|
|||||||
workflow_run.tenant_id = "test-tenant-id"
|
workflow_run.tenant_id = "test-tenant-id"
|
||||||
workflow_run.app_id = "test-app-id"
|
workflow_run.app_id = "test-app-id"
|
||||||
workflow_run.workflow_id = "test-workflow-id"
|
workflow_run.workflow_id = "test-workflow-id"
|
||||||
workflow_run.sequence_number = 1
|
|
||||||
workflow_run.type = "chat"
|
workflow_run.type = "chat"
|
||||||
workflow_run.triggered_from = "app-run"
|
workflow_run.triggered_from = "app-run"
|
||||||
workflow_run.version = "1.0"
|
workflow_run.version = "1.0"
|
||||||
|
|||||||
@ -152,7 +152,6 @@ Chat applications support session persistence, allowing previous chat history to
|
|||||||
- `data` (object) detail
|
- `data` (object) detail
|
||||||
- `id` (string) Unique ID of workflow execution
|
- `id` (string) Unique ID of workflow execution
|
||||||
- `workflow_id` (string) ID of related workflow
|
- `workflow_id` (string) ID of related workflow
|
||||||
- `sequence_number` (int) Self-increasing serial number, self-increasing in the App, starting from 1
|
|
||||||
- `created_at` (timestamp) Creation timestamp, e.g., 1705395332
|
- `created_at` (timestamp) Creation timestamp, e.g., 1705395332
|
||||||
- `event: node_started` node execution started
|
- `event: node_started` node execution started
|
||||||
- `task_id` (string) Task ID, used for request tracking and the below Stop Generate API
|
- `task_id` (string) Task ID, used for request tracking and the below Stop Generate API
|
||||||
@ -287,7 +286,7 @@ Chat applications support session persistence, allowing previous chat history to
|
|||||||
### Streaming Mode
|
### Streaming Mode
|
||||||
<CodeGroup title="Response">
|
<CodeGroup title="Response">
|
||||||
```streaming {{ title: 'Response' }}
|
```streaming {{ title: 'Response' }}
|
||||||
data: {"event": "workflow_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "sequence_number": 1, "created_at": 1679586595}}
|
data: {"event": "workflow_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "created_at": 1679586595}}
|
||||||
data: {"event": "node_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "created_at": 1679586595}}
|
data: {"event": "node_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "created_at": 1679586595}}
|
||||||
data: {"event": "node_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "execution_metadata": {"total_tokens": 63127864, "total_price": 2.378, "currency": "USD"}, "created_at": 1679586595}}
|
data: {"event": "node_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "execution_metadata": {"total_tokens": 63127864, "total_price": 2.378, "currency": "USD"}, "created_at": 1679586595}}
|
||||||
data: {"event": "workflow_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "total_tokens": 63127864, "total_steps": "1", "created_at": 1679586595, "finished_at": 1679976595}}
|
data: {"event": "workflow_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "total_tokens": 63127864, "total_steps": "1", "created_at": 1679586595, "finished_at": 1679976595}}
|
||||||
|
|||||||
@ -152,7 +152,6 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
|
|||||||
- `data` (object) 詳細
|
- `data` (object) 詳細
|
||||||
- `id` (string) ワークフロー実行の一意ID
|
- `id` (string) ワークフロー実行の一意ID
|
||||||
- `workflow_id` (string) 関連ワークフローのID
|
- `workflow_id` (string) 関連ワークフローのID
|
||||||
- `sequence_number` (int) 自己増加シリアル番号、アプリ内で自己増加し、1から始まります
|
|
||||||
- `created_at` (timestamp) 作成タイムスタンプ、例:1705395332
|
- `created_at` (timestamp) 作成タイムスタンプ、例:1705395332
|
||||||
- `event: node_started` ノード実行が開始
|
- `event: node_started` ノード実行が開始
|
||||||
- `task_id` (string) タスクID、リクエスト追跡と以下のStop Generate APIに使用
|
- `task_id` (string) タスクID、リクエスト追跡と以下のStop Generate APIに使用
|
||||||
@ -287,7 +286,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
|
|||||||
### ストリーミングモード
|
### ストリーミングモード
|
||||||
<CodeGroup title="応答">
|
<CodeGroup title="応答">
|
||||||
```streaming {{ title: '応答' }}
|
```streaming {{ title: '応答' }}
|
||||||
data: {"event": "workflow_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "sequence_number": 1, "created_at": 1679586595}}
|
data: {"event": "workflow_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "created_at": 1679586595}}
|
||||||
data: {"event": "node_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "created_at": 1679586595}}
|
data: {"event": "node_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "created_at": 1679586595}}
|
||||||
data: {"event": "node_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "execution_metadata": {"total_tokens": 63127864, "total_price": 2.378, "currency": "USD"}, "created_at": 1679586595}}
|
data: {"event": "node_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "execution_metadata": {"total_tokens": 63127864, "total_price": 2.378, "currency": "USD"}, "created_at": 1679586595}}
|
||||||
data: {"event": "workflow_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "total_tokens": 63127864, "total_steps": "1", "created_at": 1679586595, "finished_at": 1679976595}}
|
data: {"event": "workflow_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "total_tokens": 63127864, "total_steps": "1", "created_at": 1679586595, "finished_at": 1679976595}}
|
||||||
|
|||||||
@ -153,7 +153,6 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
|
|||||||
- `data` (object) 详细内容
|
- `data` (object) 详细内容
|
||||||
- `id` (string) workflow 执行 ID
|
- `id` (string) workflow 执行 ID
|
||||||
- `workflow_id` (string) 关联 Workflow ID
|
- `workflow_id` (string) 关联 Workflow ID
|
||||||
- `sequence_number` (int) 自增序号,App 内自增,从 1 开始
|
|
||||||
- `created_at` (timestamp) 开始时间
|
- `created_at` (timestamp) 开始时间
|
||||||
- `event: node_started` node 开始执行
|
- `event: node_started` node 开始执行
|
||||||
- `task_id` (string) 任务 ID,用于请求跟踪和下方的停止响应接口
|
- `task_id` (string) 任务 ID,用于请求跟踪和下方的停止响应接口
|
||||||
@ -297,7 +296,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
|
|||||||
### 流式模式
|
### 流式模式
|
||||||
<CodeGroup title="Response">
|
<CodeGroup title="Response">
|
||||||
```streaming {{ title: 'Response' }}
|
```streaming {{ title: 'Response' }}
|
||||||
data: {"event": "workflow_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "sequence_number": 1, "created_at": 1679586595}}
|
data: {"event": "workflow_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "created_at": 1679586595}}
|
||||||
data: {"event": "node_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "created_at": 1679586595}}
|
data: {"event": "node_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "created_at": 1679586595}}
|
||||||
data: {"event": "node_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "execution_metadata": {"total_tokens": 63127864, "total_price": 2.378, "currency": "USD"}, "created_at": 1679586595}}
|
data: {"event": "node_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "execution_metadata": {"total_tokens": 63127864, "total_price": 2.378, "currency": "USD"}, "created_at": 1679586595}}
|
||||||
data: {"event": "workflow_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "total_tokens": 63127864, "total_steps": "1", "created_at": 1679586595, "finished_at": 1679976595}}
|
data: {"event": "workflow_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "total_tokens": 63127864, "total_steps": "1", "created_at": 1679586595, "finished_at": 1679976595}}
|
||||||
|
|||||||
@ -103,7 +103,6 @@ Workflow applications offers non-session support and is ideal for translation, a
|
|||||||
- `data` (object) detail
|
- `data` (object) detail
|
||||||
- `id` (string) Unique ID of workflow execution
|
- `id` (string) Unique ID of workflow execution
|
||||||
- `workflow_id` (string) ID of related workflow
|
- `workflow_id` (string) ID of related workflow
|
||||||
- `sequence_number` (int) Self-increasing serial number, self-increasing in the App, starting from 1
|
|
||||||
- `created_at` (timestamp) Creation timestamp, e.g., 1705395332
|
- `created_at` (timestamp) Creation timestamp, e.g., 1705395332
|
||||||
- `event: node_started` node execution started
|
- `event: node_started` node execution started
|
||||||
- `task_id` (string) Task ID, used for request tracking and the below Stop Generate API
|
- `task_id` (string) Task ID, used for request tracking and the below Stop Generate API
|
||||||
@ -241,7 +240,7 @@ Workflow applications offers non-session support and is ideal for translation, a
|
|||||||
### Streaming Mode
|
### Streaming Mode
|
||||||
<CodeGroup title="Response">
|
<CodeGroup title="Response">
|
||||||
```streaming {{ title: 'Response' }}
|
```streaming {{ title: 'Response' }}
|
||||||
data: {"event": "workflow_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "sequence_number": 1, "created_at": 1679586595}}
|
data: {"event": "workflow_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "created_at": 1679586595}}
|
||||||
data: {"event": "node_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "created_at": 1679586595}}
|
data: {"event": "node_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "created_at": 1679586595}}
|
||||||
data: {"event": "node_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "execution_metadata": {"total_tokens": 63127864, "total_price": 2.378, "currency": "USD"}, "created_at": 1679586595}}
|
data: {"event": "node_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "execution_metadata": {"total_tokens": 63127864, "total_price": 2.378, "currency": "USD"}, "created_at": 1679586595}}
|
||||||
data: {"event": "workflow_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "total_tokens": 63127864, "total_steps": "1", "created_at": 1679586595, "finished_at": 1679976595}}
|
data: {"event": "workflow_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "total_tokens": 63127864, "total_steps": "1", "created_at": 1679586595, "finished_at": 1679976595}}
|
||||||
|
|||||||
@ -104,7 +104,6 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
|
|||||||
- `data` (object) 詳細
|
- `data` (object) 詳細
|
||||||
- `id` (string) ワークフロー実行の一意の ID
|
- `id` (string) ワークフロー実行の一意の ID
|
||||||
- `workflow_id` (string) 関連するワークフローの ID
|
- `workflow_id` (string) 関連するワークフローの ID
|
||||||
- `sequence_number` (int) 自己増加シリアル番号、アプリ内で自己増加し、1 から始まります
|
|
||||||
- `created_at` (timestamp) 作成タイムスタンプ、例:1705395332
|
- `created_at` (timestamp) 作成タイムスタンプ、例:1705395332
|
||||||
- `event: node_started` ノード実行開始
|
- `event: node_started` ノード実行開始
|
||||||
- `task_id` (string) タスク ID、リクエスト追跡と以下の Stop Generate API に使用
|
- `task_id` (string) タスク ID、リクエスト追跡と以下の Stop Generate API に使用
|
||||||
@ -242,7 +241,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
|
|||||||
### ストリーミングモード
|
### ストリーミングモード
|
||||||
<CodeGroup title="応答">
|
<CodeGroup title="応答">
|
||||||
```streaming {{ title: '応答' }}
|
```streaming {{ title: '応答' }}
|
||||||
data: {"event": "workflow_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "sequence_number": 1, "created_at": 1679586595}}
|
data: {"event": "workflow_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "created_at": 1679586595}}
|
||||||
data: {"event": "node_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "created_at": 1679586595}}
|
data: {"event": "node_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "created_at": 1679586595}}
|
||||||
data: {"event": "node_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "execution_metadata": {"total_tokens": 63127864, "total_price": 2.378, "currency": "USD"}, "created_at": 1679586595}}
|
data: {"event": "node_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "execution_metadata": {"total_tokens": 63127864, "total_price": 2.378, "currency": "USD"}, "created_at": 1679586595}}
|
||||||
data: {"event": "workflow_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "total_tokens": 63127864, "total_steps": "1", "created_at": 1679586595, "finished_at": 1679976595}}
|
data: {"event": "workflow_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "total_tokens": 63127864, "total_steps": "1", "created_at": 1679586595, "finished_at": 1679976595}}
|
||||||
|
|||||||
@ -98,7 +98,6 @@ Workflow 应用无会话支持,适合用于翻译/文章写作/总结 AI 等
|
|||||||
- `data` (object) 详细内容
|
- `data` (object) 详细内容
|
||||||
- `id` (string) workflow 执行 ID
|
- `id` (string) workflow 执行 ID
|
||||||
- `workflow_id` (string) 关联 Workflow ID
|
- `workflow_id` (string) 关联 Workflow ID
|
||||||
- `sequence_number` (int) 自增序号,App 内自增,从 1 开始
|
|
||||||
- `created_at` (timestamp) 开始时间
|
- `created_at` (timestamp) 开始时间
|
||||||
- `event: node_started` node 开始执行
|
- `event: node_started` node 开始执行
|
||||||
- `task_id` (string) 任务 ID,用于请求跟踪和下方的停止响应接口
|
- `task_id` (string) 任务 ID,用于请求跟踪和下方的停止响应接口
|
||||||
@ -232,7 +231,7 @@ Workflow 应用无会话支持,适合用于翻译/文章写作/总结 AI 等
|
|||||||
### Streaming Mode
|
### Streaming Mode
|
||||||
<CodeGroup title="Response">
|
<CodeGroup title="Response">
|
||||||
```streaming {{ title: 'Response' }}
|
```streaming {{ title: 'Response' }}
|
||||||
data: {"event": "workflow_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "sequence_number": 1, "created_at": 1679586595}}
|
data: {"event": "workflow_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "created_at": 1679586595}}
|
||||||
data: {"event": "node_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "created_at": 1679586595}}
|
data: {"event": "node_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "created_at": 1679586595}}
|
||||||
data: {"event": "node_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "execution_metadata": {"total_tokens": 63127864, "total_price": 2.378, "currency": "USD"}, "created_at": 1679586595}}
|
data: {"event": "node_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "execution_metadata": {"total_tokens": 63127864, "total_price": 2.378, "currency": "USD"}, "created_at": 1679586595}}
|
||||||
data: {"event": "workflow_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "total_tokens": 63127864, "total_steps": "1", "created_at": 1679586595, "finished_at": 1679976595}}
|
data: {"event": "workflow_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "total_tokens": 63127864, "total_steps": "1", "created_at": 1679586595, "finished_at": 1679976595}}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { memo } from 'react'
|
|||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useIsChatMode } from '../hooks'
|
import { useIsChatMode } from '../hooks'
|
||||||
import { useStore } from '../store'
|
import { useStore } from '../store'
|
||||||
|
import { formatWorkflowRunIdentifier } from '../utils'
|
||||||
import { ClockPlay } from '@/app/components/base/icons/src/vender/line/time'
|
import { ClockPlay } from '@/app/components/base/icons/src/vender/line/time'
|
||||||
|
|
||||||
const RunningTitle = () => {
|
const RunningTitle = () => {
|
||||||
@ -12,7 +13,7 @@ const RunningTitle = () => {
|
|||||||
return (
|
return (
|
||||||
<div className='flex h-[18px] items-center text-xs text-gray-500'>
|
<div className='flex h-[18px] items-center text-xs text-gray-500'>
|
||||||
<ClockPlay className='mr-1 h-3 w-3 text-gray-500' />
|
<ClockPlay className='mr-1 h-3 w-3 text-gray-500' />
|
||||||
<span>{isChatMode ? `Test Chat#${historyWorkflowData?.sequence_number}` : `Test Run#${historyWorkflowData?.sequence_number}`}</span>
|
<span>{isChatMode ? `Test Chat${formatWorkflowRunIdentifier(historyWorkflowData?.finished_at)}` : `Test Run${formatWorkflowRunIdentifier(historyWorkflowData?.finished_at)}`}</span>
|
||||||
<span className='mx-1'>·</span>
|
<span className='mx-1'>·</span>
|
||||||
<span className='ml-1 flex h-[18px] items-center rounded-[5px] border border-indigo-300 bg-white/[0.48] px-1 text-[10px] font-semibold uppercase text-indigo-600'>
|
<span className='ml-1 flex h-[18px] items-center rounded-[5px] border border-indigo-300 bg-white/[0.48] px-1 text-[10px] font-semibold uppercase text-indigo-600'>
|
||||||
{t('workflow.common.viewOnly')}
|
{t('workflow.common.viewOnly')}
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import {
|
|||||||
useWorkflowRun,
|
useWorkflowRun,
|
||||||
} from '../hooks'
|
} from '../hooks'
|
||||||
import { ControlMode, WorkflowRunningStatus } from '../types'
|
import { ControlMode, WorkflowRunningStatus } from '../types'
|
||||||
|
import { formatWorkflowRunIdentifier } from '../utils'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
import {
|
import {
|
||||||
PortalToFollowElem,
|
PortalToFollowElem,
|
||||||
@ -199,7 +200,7 @@ const ViewHistory = ({
|
|||||||
item.id === historyWorkflowData?.id && 'text-text-accent',
|
item.id === historyWorkflowData?.id && 'text-text-accent',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{`Test ${isChatMode ? 'Chat' : 'Run'} #${item.sequence_number}`}
|
{`Test ${isChatMode ? 'Chat' : 'Run'}${formatWorkflowRunIdentifier(item.finished_at)}`}
|
||||||
</div>
|
</div>
|
||||||
<div className='flex items-center text-xs leading-[18px] text-text-tertiary'>
|
<div className='flex items-center text-xs leading-[18px] text-text-tertiary'>
|
||||||
{item.created_by_account?.name} · {formatTimeFromNow((item.finished_at || item.created_at) * 1000)}
|
{item.created_by_account?.name} · {formatTimeFromNow((item.finished_at || item.created_at) * 1000)}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import {
|
|||||||
useWorkflowStore,
|
useWorkflowStore,
|
||||||
} from '../../store'
|
} from '../../store'
|
||||||
import { useWorkflowRun } from '../../hooks'
|
import { useWorkflowRun } from '../../hooks'
|
||||||
|
import { formatWorkflowRunIdentifier } from '../../utils'
|
||||||
import UserInput from './user-input'
|
import UserInput from './user-input'
|
||||||
import Chat from '@/app/components/base/chat/chat'
|
import Chat from '@/app/components/base/chat/chat'
|
||||||
import type { ChatItem, ChatItemInTree } from '@/app/components/base/chat/types'
|
import type { ChatItem, ChatItemInTree } from '@/app/components/base/chat/types'
|
||||||
@ -99,7 +100,7 @@ const ChatRecord = () => {
|
|||||||
{fetched && (
|
{fetched && (
|
||||||
<>
|
<>
|
||||||
<div className='flex shrink-0 items-center justify-between p-4 pb-1 text-base font-semibold text-text-primary'>
|
<div className='flex shrink-0 items-center justify-between p-4 pb-1 text-base font-semibold text-text-primary'>
|
||||||
{`TEST CHAT#${historyWorkflowData?.sequence_number}`}
|
{`TEST CHAT${formatWorkflowRunIdentifier(historyWorkflowData?.finished_at)}`}
|
||||||
<div
|
<div
|
||||||
className='flex h-6 w-6 cursor-pointer items-center justify-center'
|
className='flex h-6 w-6 cursor-pointer items-center justify-center'
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import type { WorkflowDataUpdater } from '../types'
|
|||||||
import Run from '../run'
|
import Run from '../run'
|
||||||
import { useStore } from '../store'
|
import { useStore } from '../store'
|
||||||
import { useWorkflowUpdate } from '../hooks'
|
import { useWorkflowUpdate } from '../hooks'
|
||||||
|
import { formatWorkflowRunIdentifier } from '../utils'
|
||||||
|
|
||||||
const Record = () => {
|
const Record = () => {
|
||||||
const historyWorkflowData = useStore(s => s.historyWorkflowData)
|
const historyWorkflowData = useStore(s => s.historyWorkflowData)
|
||||||
@ -20,7 +21,7 @@ const Record = () => {
|
|||||||
return (
|
return (
|
||||||
<div className='flex h-full w-[400px] flex-col rounded-l-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xl'>
|
<div className='flex h-full w-[400px] flex-col rounded-l-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xl'>
|
||||||
<div className='system-xl-semibold flex items-center justify-between p-4 pb-0 text-text-primary'>
|
<div className='system-xl-semibold flex items-center justify-between p-4 pb-0 text-text-primary'>
|
||||||
{`Test Run#${historyWorkflowData?.sequence_number}`}
|
{`Test Run${formatWorkflowRunIdentifier(historyWorkflowData?.finished_at)}`}
|
||||||
</div>
|
</div>
|
||||||
<Run
|
<Run
|
||||||
runID={historyWorkflowData?.id || ''}
|
runID={historyWorkflowData?.id || ''}
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import { useStore } from '../store'
|
|||||||
import {
|
import {
|
||||||
WorkflowRunningStatus,
|
WorkflowRunningStatus,
|
||||||
} from '../types'
|
} from '../types'
|
||||||
|
import { formatWorkflowRunIdentifier } from '../utils'
|
||||||
import Toast from '../../base/toast'
|
import Toast from '../../base/toast'
|
||||||
import InputsPanel from './inputs-panel'
|
import InputsPanel from './inputs-panel'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
@ -88,7 +89,7 @@ const WorkflowPreview = () => {
|
|||||||
onMouseDown={startResizing}
|
onMouseDown={startResizing}
|
||||||
/>
|
/>
|
||||||
<div className='flex items-center justify-between p-4 pb-1 text-base font-semibold text-text-primary'>
|
<div className='flex items-center justify-between p-4 pb-1 text-base font-semibold text-text-primary'>
|
||||||
{`Test Run${!workflowRunningData?.result.sequence_number ? '' : `#${workflowRunningData?.result.sequence_number}`}`}
|
{`Test Run${formatWorkflowRunIdentifier(workflowRunningData?.result.finished_at)}`}
|
||||||
<div className='cursor-pointer p-1' onClick={() => handleCancelDebugAndPreviewPanel()}>
|
<div className='cursor-pointer p-1' onClick={() => handleCancelDebugAndPreviewPanel()}>
|
||||||
<RiCloseLine className='h-4 w-4 text-text-tertiary' />
|
<RiCloseLine className='h-4 w-4 text-text-tertiary' />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -360,7 +360,6 @@ export type WorkflowRunningData = {
|
|||||||
message_id?: string
|
message_id?: string
|
||||||
conversation_id?: string
|
conversation_id?: string
|
||||||
result: {
|
result: {
|
||||||
sequence_number?: number
|
|
||||||
workflow_id?: string
|
workflow_id?: string
|
||||||
inputs?: string
|
inputs?: string
|
||||||
process_data?: string
|
process_data?: string
|
||||||
@ -383,9 +382,9 @@ export type WorkflowRunningData = {
|
|||||||
|
|
||||||
export type HistoryWorkflowData = {
|
export type HistoryWorkflowData = {
|
||||||
id: string
|
id: string
|
||||||
sequence_number: number
|
|
||||||
status: string
|
status: string
|
||||||
conversation_id?: string
|
conversation_id?: string
|
||||||
|
finished_at?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ChangeType {
|
export enum ChangeType {
|
||||||
|
|||||||
@ -33,3 +33,22 @@ export const isEventTargetInputArea = (target: HTMLElement) => {
|
|||||||
if (target.contentEditable === 'true')
|
if (target.contentEditable === 'true')
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format workflow run identifier using finished_at timestamp
|
||||||
|
* @param finishedAt - Unix timestamp in seconds
|
||||||
|
* @param fallbackText - Text to show when finishedAt is not available (default: 'Running')
|
||||||
|
* @returns Formatted string like " (14:30:25)" or " (Running)"
|
||||||
|
*/
|
||||||
|
export const formatWorkflowRunIdentifier = (finishedAt?: number, fallbackText = 'Running'): string => {
|
||||||
|
if (!finishedAt)
|
||||||
|
return ` (${fallbackText})`
|
||||||
|
|
||||||
|
const date = new Date(finishedAt * 1000)
|
||||||
|
const timeStr = date.toLocaleTimeString([], {
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
second: '2-digit',
|
||||||
|
})
|
||||||
|
return ` (${timeStr})`
|
||||||
|
}
|
||||||
|
|||||||
@ -278,7 +278,6 @@ export type WorkflowLogsRequest = {
|
|||||||
|
|
||||||
export type WorkflowRunDetailResponse = {
|
export type WorkflowRunDetailResponse = {
|
||||||
id: string
|
id: string
|
||||||
sequence_number: number
|
|
||||||
version: string
|
version: string
|
||||||
graph: {
|
graph: {
|
||||||
nodes: Node[]
|
nodes: Node[]
|
||||||
|
|||||||
@ -152,7 +152,6 @@ export type WorkflowStartedResponse = {
|
|||||||
data: {
|
data: {
|
||||||
id: string
|
id: string
|
||||||
workflow_id: string
|
workflow_id: string
|
||||||
sequence_number: number
|
|
||||||
created_at: number
|
created_at: number
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -289,7 +288,6 @@ export type AgentLogResponse = {
|
|||||||
|
|
||||||
export type WorkflowRunHistory = {
|
export type WorkflowRunHistory = {
|
||||||
id: string
|
id: string
|
||||||
sequence_number: number
|
|
||||||
version: string
|
version: string
|
||||||
conversation_id?: string
|
conversation_id?: string
|
||||||
message_id?: string
|
message_id?: string
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user