Skip to content

Commit 1972fe0

Browse files
authored
Merge branch 'main' into tyler/project-reduce-ci-costs
2 parents 9d7e3f9 + ce6922d commit 1972fe0

File tree

4 files changed

+81
-12
lines changed

4 files changed

+81
-12
lines changed

apps/dojo/e2e/featurePages/ToolBaseGenUIPage.ts

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -125,19 +125,19 @@ export class ToolBaseGenUIPage {
125125
return mainHaikuContent;
126126
}
127127

128-
async checkHaikuDisplay(page: Page): Promise<void> {
129-
const chatHaikuContent = await this.extractChatHaikuContent(page);
130-
131-
await page.waitForTimeout(3000);
132-
133-
// Check that the haiku exists somewhere in the carousel
128+
private async carouselIncludesHaiku(
129+
page: Page,
130+
chatHaikuContent: string,
131+
): Promise<boolean> {
134132
const carousel = page.locator('[data-testid="haiku-carousel"]');
135-
await carousel.waitFor({ state: "visible", timeout: 10000 });
133+
134+
if (!(await carousel.isVisible())) {
135+
return false;
136+
}
136137

137138
const allCarouselCards = carousel.locator('[data-testid="haiku-card"]');
138139
const cardCount = await allCarouselCards.count();
139140

140-
let foundMatch = false;
141141
for (let i = 0; i < cardCount; i++) {
142142
const card = allCarouselCards.nth(i);
143143
const lines = card.locator('[data-testid="haiku-japanese-line"]');
@@ -151,11 +151,21 @@ export class ToolBaseGenUIPage {
151151

152152
const cardContent = cardLines.join("").replace(/\s/g, "");
153153
if (cardContent === chatHaikuContent) {
154-
foundMatch = true;
155-
break;
154+
return true;
156155
}
157156
}
158157

159-
expect(foundMatch).toBe(true);
158+
return false;
159+
}
160+
161+
async checkHaikuDisplay(page: Page): Promise<void> {
162+
const chatHaikuContent = await this.extractChatHaikuContent(page);
163+
164+
await expect
165+
.poll(
166+
async () => this.carouselIncludesHaiku(page, chatHaikuContent),
167+
{ timeout: 20000, intervals: [500, 1000, 2000] },
168+
)
169+
.toBe(true);
160170
}
161171
}

integrations/langgraph/python/ag_ui_langgraph/agent.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@
44
import inspect
55

66
from langgraph.graph.state import CompiledStateGraph
7-
from langchain.schema import BaseMessage, SystemMessage
7+
8+
try:
9+
from langchain.schema import BaseMessage, SystemMessage
10+
except ImportError:
11+
# Langchain >= 1.0.0
12+
from langchain_core.messages import BaseMessage, SystemMessage
13+
814
from langchain_core.runnables import RunnableConfig, ensure_config
915
from langchain_core.messages import HumanMessage
1016
from langgraph.types import Command

sdks/community/go/pkg/encoding/sse/writer.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"io"
88
"log/slog"
9+
"net/http"
910
"strings"
1011
"sync"
1112
"time"
@@ -67,6 +68,9 @@ func (w *SSEWriter) WriteBytes(ctx context.Context, writer io.Writer, event []by
6768
return fmt.Errorf("SSE flush failed: %w", err)
6869
}
6970
}
71+
if flusher, ok := writer.(flusherWithoutError); ok {
72+
flusher.Flush()
73+
}
7074
return nil
7175
}
7276

@@ -116,6 +120,9 @@ func (w *SSEWriter) WriteEventWithType(ctx context.Context, writer io.Writer, ev
116120
return fmt.Errorf("SSE flush failed: %w", err)
117121
}
118122
}
123+
if flusher, ok := writer.(flusherWithoutError); ok {
124+
flusher.Flush()
125+
}
119126

120127
return nil
121128
}
@@ -187,6 +194,10 @@ type flusher interface {
187194
Flush() error
188195
}
189196

197+
// flusherWithoutError is a type alias for http.Flusher.
198+
// It is used to flush the writer without returning an error.
199+
type flusherWithoutError = http.Flusher
200+
190201
// CustomEvent is a simple implementation of events.Event for error and custom events
191202
type CustomEvent struct {
192203
events.BaseEvent

sdks/community/go/pkg/encoding/sse/writer_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ func (fw *flushWriter) Flush() error {
6868
return fw.flushError
6969
}
7070

71+
type httpFlushWriter struct {
72+
bytes.Buffer
73+
flushCalled bool
74+
}
75+
76+
func (fw *httpFlushWriter) Flush() {
77+
fw.flushCalled = true
78+
}
79+
7180
func TestNewSSEWriter(t *testing.T) {
7281
writer := NewSSEWriter()
7382
if writer == nil {
@@ -451,6 +460,39 @@ func TestSSEWriter_Flushing(t *testing.T) {
451460
}
452461
}
453462

463+
func TestSSEWriter_HTTPFlusherFallback(t *testing.T) {
464+
ctx := context.Background()
465+
writer := NewSSEWriter()
466+
467+
t.Run("WriteEvent", func(t *testing.T) {
468+
fw := &httpFlushWriter{}
469+
event := &mockEvent{
470+
BaseEvent: events.BaseEvent{
471+
EventType: events.EventTypeCustom,
472+
},
473+
}
474+
475+
if err := writer.WriteEvent(ctx, fw, event); err != nil {
476+
t.Fatalf("unexpected error: %v", err)
477+
}
478+
479+
if !fw.flushCalled {
480+
t.Error("expected fallback flusher to be called")
481+
}
482+
})
483+
484+
t.Run("WriteBytes", func(t *testing.T) {
485+
fw := &httpFlushWriter{}
486+
if err := writer.WriteBytes(ctx, fw, []byte(`{"test":"data"}`)); err != nil {
487+
t.Fatalf("unexpected error: %v", err)
488+
}
489+
490+
if !fw.flushCalled {
491+
t.Error("expected fallback flusher to be called")
492+
}
493+
})
494+
}
495+
454496
func TestCustomEvent(t *testing.T) {
455497
t.Run("Data operations", func(t *testing.T) {
456498
event := &CustomEvent{}

0 commit comments

Comments
 (0)