Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 54b94e5

Browse files
stream events
1 parent 92495d2 commit 54b94e5

File tree

3 files changed

+60
-10
lines changed

3 files changed

+60
-10
lines changed

‎src/app/workflow.py‎

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import asyncio
2+
import time
23

34
from workflows import Context, Workflow, step
4-
from workflows.events import StartEvent, StopEvent
5+
from workflows.events import StartEvent, StopEvent, Event
56
import logging
7+
from datetime import datetime
68

79
logger = logging.getLogger(__name__)
810

@@ -11,15 +13,30 @@ class PingEvent(StartEvent):
1113
message: str
1214

1315

14-
class PongEvent(StopEvent):
16+
class PongEvent(Event):
1517
message: str
1618

1719

20+
class WorkflowCompletedEvent(StopEvent):
21+
timestamp: str
22+
23+
1824
class DefaultWorkflow(Workflow):
1925
@step
20-
async def start(self, event: PingEvent, context: Context) -> PongEvent:
26+
async def start(self, event: PingEvent, context: Context) -> WorkflowCompletedEvent:
27+
start = time.monotonic()
2128
logger.info(f"Received message: {event.message}")
22-
return PongEvent(message=f"PONG for '{event.message}'")
29+
for i in range(5):
30+
logger.info(f"Processing message: {event.message} {i}")
31+
elapsed = (time.monotonic() - start) * 1000
32+
context.write_event_to_stream(
33+
PongEvent(message=f"+{elapsed:.0f}ms PONG {i + 1}/5 ")
34+
)
35+
await asyncio.sleep(0.2)
36+
return WorkflowCompletedEvent(
37+
timestamp="workflow completed at "
38+
+ datetime.now().isoformat(timespec="seconds")
39+
)
2340

2441

2542
workflow = DefaultWorkflow()

‎ui/src/index.css‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,15 @@ body {
8383
filter: blur(28px) saturate(110%);
8484
}
8585
}
86+
87+
/* Simple fade-in-up animation for streamed items */
88+
@keyframes fade-in-left {
89+
from {
90+
opacity: 0;
91+
transform: translateX(36px);
92+
}
93+
to {
94+
opacity: 1;
95+
transform: translateX(0);
96+
}
97+
}

‎ui/src/pages/Home.tsx‎

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ export default function Home() {
1313
llama-ui to call the workflow. Customize this app with your own
1414
workflow and UI.
1515
</div>
16-
<div className="flex flex-row gap-4 items-center justify-center w-full">
16+
<div className="flex flex-row gap-4 items-start justify-center w-full">
1717
{taskId ? (
18-
<HandlerOuput handlerId={taskId} />
18+
<HandlerOutput handlerId={taskId} />
1919
) : (
2020
<Output>
2121
<span className="text-black/60 dark:text-white/60">
@@ -71,14 +71,35 @@ function RunButton({
7171
);
7272
}
7373

74-
function HandlerOuput({ handlerId }: { handlerId: string }) {
74+
function HandlerOutput({ handlerId }: { handlerId: string }) {
75+
// stream events and result from the workflow
7576
const taskData = useWorkflowTask(handlerId);
7677

77-
const result = taskData.events.find((event) =>
78+
// read workflow events here
79+
const pongs = taskData.events.filter((event) =>
7880
event.type.match(/PongEvent$/),
79-
) as { type: string; data: { message: string } } | undefined;
81+
) as { type: string; data: { message: string } }[];
82+
const completed = taskData.events.find((event) =>
83+
event.type.match(/WorkflowCompletedEvent$/),
84+
) as { type: string; data: { timestamp: string } } | undefined;
8085

81-
return <Output>{result ? result.data.message : "Running... "}</Output>;
86+
return (
87+
<div className="flex flex-col gap-4 w-full min-h-60">
88+
<Output>{completed ? completed.data.timestamp : "Running... "}</Output>
89+
{pongs.map((pong, index) => (
90+
<span
91+
className="text-black/60 dark:text-white/60 text-sm m-0"
92+
key={pong.data.message}
93+
style={{
94+
animation: "fade-in-left 80ms ease-out both",
95+
willChange: "opacity, transform",
96+
}}
97+
>
98+
{pong.data.message}
99+
</span>
100+
))}
101+
</div>
102+
);
82103
}
83104

84105
function Output({ children }: { children: React.ReactNode }) {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /