@@ -833,84 +833,64 @@ function ExecuteCodeStory({ onSendMessage }: { onSendMessage: (content: string)
833833 role : "input" ,
834834 data : {
835835 language : "python" ,
836- code : `import matplotlib.pyplot as plt
837- import matplotlib.ticker as mticker
838-
839- categories = ['Cloud', 'Enterprise', 'Consumer', 'Services', 'Hardware']
840- q3_revenue = [1.42, 1.05, 0.82, 0.58, 0.33]
841- q2_revenue = [1.18, 0.94, 0.79, 0.52, 0.31]
842-
843- x = range(len(categories))
844- width = 0.35
845-
846- fig, ax = plt.subplots(figsize=(10, 6))
847- bars_q2 = ax.bar([i - width/2 for i in x], q2_revenue, width, label='Q2', color='#94a3b8')
848- bars_q3 = ax.bar([i + width/2 for i in x], q3_revenue, width, label='Q3', color='#3b82f6')
849-
850- ax.set_ylabel('Revenue ($B)')
851- ax.set_title('Revenue by Segment: Q2 vs Q3 2025')
852- ax.set_xticks(x)
853- ax.set_xticklabels(categories)
854- ax.yaxis.set_major_formatter(mticker.FormatStrFormatter('$%.2f'))
855- ax.legend()
856- ax.bar_label(bars_q3, fmt='$%.2f', padding=3, fontsize=9)
836+ code : `import numpy as np
837+ import matplotlib.pyplot as plt
838+ from matplotlib.collections import LineCollection
839+
840+ # Simulate the Lorenz system
841+ sigma, rho, beta = 10, 28, 8/3
842+ dt = 0.002
843+ steps = 20000
844+
845+ xyz = np.empty((steps, 3))
846+ xyz[0] = [0.1, 0, 0]
847+ for i in range(1, steps):
848+ x, y, z = xyz[i-1]
849+ xyz[i] = xyz[i-1] + dt * np.array([
850+ sigma * (y - x),
851+ x * (rho - z) - y,
852+ x * y - beta * z,
853+ ])
854+
855+ fig, ax = plt.subplots(figsize=(10, 7), facecolor='#0f172a')
856+ ax.set_facecolor('#0f172a')
857+
858+ # Color by velocity (speed of change)
859+ velocity = np.linalg.norm(np.diff(xyz, axis=0), axis=1)
860+ points = xyz[:-1, [0, 2]] # project onto x-z plane
861+ segments = np.stack([points[:-1], points[1:]], axis=1)
862+
863+ lc = LineCollection(segments, cmap='turbo', linewidths=0.6, alpha=0.9)
864+ lc.set_array(velocity[:-1])
865+ ax.add_collection(lc)
866+ ax.autoscale()
867+ ax.set_xlabel('x', color='#94a3b8')
868+ ax.set_ylabel('z', color='#94a3b8')
869+ ax.set_title('Lorenz Attractor — Colored by Velocity', color='white', fontsize=14)
870+ ax.tick_params(colors='#475569')
871+ for spine in ax.spines.values():
872+ spine.set_color('#1e293b')
857873plt.tight_layout()
858- plt.savefig('revenue_comparison .png', dpi=150 )
859- print("Chart saved successfully ")` ,
874+ plt.savefig('lorenz .png', dpi=180, facecolor='#0f172a' )
875+ print(f"Rendered {steps:,} steps, max velocity: {velocity.max():.1f} ")` ,
860876 } ,
861877 } ;
862878
863879 const chartOutputArtifact : Artifact = {
864880 id : "chart-output-1" ,
865- type : "chart " ,
866- title : "Revenue by Segment " ,
881+ type : "image " ,
882+ title : "Lorenz Attractor " ,
867883 role : "output" ,
868- data : {
869- spec : {
870- $schema : "https://vega.github.io/schema/vega-lite/v6.json" ,
871- title : "Revenue by Segment: Q2 vs Q3 2025" ,
872- width : 500 ,
873- height : 300 ,
874- data : {
875- values : [
876- { segment : "Cloud" , quarter : "Q2" , revenue : 1.18 } ,
877- { segment : "Cloud" , quarter : "Q3" , revenue : 1.42 } ,
878- { segment : "Enterprise" , quarter : "Q2" , revenue : 0.94 } ,
879- { segment : "Enterprise" , quarter : "Q3" , revenue : 1.05 } ,
880- { segment : "Consumer" , quarter : "Q2" , revenue : 0.79 } ,
881- { segment : "Consumer" , quarter : "Q3" , revenue : 0.82 } ,
882- { segment : "Services" , quarter : "Q2" , revenue : 0.52 } ,
883- { segment : "Services" , quarter : "Q3" , revenue : 0.58 } ,
884- { segment : "Hardware" , quarter : "Q2" , revenue : 0.31 } ,
885- { segment : "Hardware" , quarter : "Q3" , revenue : 0.33 } ,
886- ] ,
887- } ,
888- mark : "bar" ,
889- encoding : {
890- x : { field : "segment" , type : "nominal" , title : "Segment" , axis : { labelAngle : 0 } } ,
891- xOffset : { field : "quarter" } ,
892- y : {
893- field : "revenue" ,
894- type : "quantitative" ,
895- title : "Revenue ($B)" ,
896- } ,
897- color : {
898- field : "quarter" ,
899- type : "nominal" ,
900- scale : { range : [ "#94a3b8" , "#3b82f6" ] } ,
901- title : "Quarter" ,
902- } ,
903- } ,
904- } ,
905- } ,
884+ mimeType : "image/png" ,
885+ data : { src : "/story-assets/lorenz.png" } ,
906886 } ;
907887
908888 const stdoutArtifact : Artifact = {
909889 id : "py-stdout-1" ,
910890 type : "code" ,
911891 title : "stdout" ,
912892 role : "output" ,
913- data : { language : "text" , code : "Chart saved successfully " } ,
893+ data : { language : "text" , code : "Rendered 20,000 steps, max velocity: 46.3 " } ,
914894 } ;
915895
916896 const displaySelectionArtifact : Artifact = {
@@ -966,31 +946,30 @@ print("Chart saved successfully")`,
966946 {
967947 id : "py-1" ,
968948 role : "user" ,
969- content : "Can you visualize Q2 vs Q3 revenue by business segment?" ,
949+ content :
950+ "Simulate the Lorenz attractor and visualize the chaotic trajectory colored by velocity." ,
970951 timestamp : new Date ( "2025-10-20T15:10:00" ) ,
971952 } ,
972953 {
973954 id : "py-2" ,
974955 role : "assistant" ,
975956 model : "openai/gpt-5.3" ,
976- content : `I created a grouped bar chart comparing Q2 and Q3 revenue across all five business segments.
977-
978- **Key highlights:**
979- - **Cloud** led growth with **$1.42B** in Q3, up 20% from Q2
980- - **Enterprise** crossed $1B for the first time at **$1.05B**
981- - **Consumer** and **Services** showed steady single-digit growth
982- - **Hardware** remained stable at **$0.33B**
957+ content : `Here's the Lorenz attractor projected onto the x-z plane, with each point colored by its instantaneous velocity through phase space.
983958
984- Total Q3 revenue of **$4.20B** represents a **12.3%** increase over Q2's $3.74B.` ,
959+ **What you're seeing:**
960+ - The system traces two lobes — the classic "butterfly" shape of deterministic chaos
961+ - **High-velocity regions** (bright yellow) occur during transitions between lobes, where the trajectory is flung across the attractor
962+ - **Low-velocity regions** (deep purple) mark the tight spirals where the system lingers before switching
963+ - Despite being fully deterministic (\u03C3=10, \u03C1=28, \u03B2=8/3), the trajectory never repeats — a hallmark of strange attractors` ,
985964 timestamp : new Date ( "2025-10-20T15:10:12" ) ,
986965 usage : {
987- inputTokens : 85 ,
988- outputTokens : 310 ,
989- totalTokens : 395 ,
990- cost : 0.0066 ,
966+ inputTokens : 92 ,
967+ outputTokens : 380 ,
968+ totalTokens : 472 ,
969+ cost : 0.0079 ,
991970 firstTokenMs : 3800 ,
992971 totalDurationMs : 7200 ,
993- tokensPerSecond : 43.1 ,
972+ tokensPerSecond : 52.8 ,
994973 } ,
995974 artifacts : [ chartOutputArtifact , displaySelectionArtifact ] ,
996975 toolExecutionRounds : pythonRounds ,
@@ -1011,11 +990,11 @@ export const ExecuteCode: Story = {
1011990 const canvas = within ( canvasElement ) ;
1012991
1013992 // Verify user message
1014- await expect ( canvas . getByText ( / Q 2 v s Q 3 r e v e n u e / ) ) . toBeInTheDocument ( ) ;
993+ await expect ( canvas . getByText ( / S i m u l a t e t h e L o r e n z a t t r a c t o r / ) ) . toBeInTheDocument ( ) ;
1015994
1016995 // Verify assistant content has key data points
1017- await expect ( canvas . getByText ( / \$ 1 \. 4 2 B / ) ) . toBeInTheDocument ( ) ;
1018- await expect ( canvas . getByText ( / 1 2 \. 3 % / ) ) . toBeInTheDocument ( ) ;
996+ await expect ( canvas . getByText ( / b u t t e r f l y / ) ) . toBeInTheDocument ( ) ;
997+ await expect ( canvas . getByText ( / s t r a n g e a t t r a c t o r s / ) ) . toBeInTheDocument ( ) ;
1019998
1020999 // Verify tool execution block is rendered (2 tools across 2 rounds)
10211000 await expect ( canvas . getByText ( / 2 t o o l s / ) ) . toBeInTheDocument ( ) ;
0 commit comments