@@ -6,15 +6,13 @@ import "./marked-dedupe";
66import "@mariozechner/mini-lit/dist/MarkdownBlock.js" ;
77import "@mariozechner/mini-lit/dist/CodeBlock.js" ;
88import { html , nothing , render , type TemplateResult } from "lit" ;
9- import { unsafeHTML } from "lit/directives/unsafe-html.js" ;
109import {
1110 Activity ,
1211 Ban ,
1312 Brain ,
1413 Check ,
1514 ChevronRight ,
1615 Clock3 ,
17- Code2 ,
1816 Copy ,
1917 FileImage ,
2018 FileText ,
@@ -71,16 +69,6 @@ import {
7169} from "./core-bridge" ;
7270import { buildTimeline , toolRowKind , type TimelineItem , type ToolPayload , type ToolRowModel } from "./timeline" ;
7371import { CONNECTOR_NAMES , connectorLinksIn , stripConnectorLinks , type ConnectorLink } from "./connector-link" ;
74- import {
75- miniappsIn ,
76- miniappFrameSrc ,
77- miniappSourceSrc ,
78- formatMiniappHtml ,
79- currentMiniappTheme ,
80- stripMiniappDirectives ,
81- type MiniappEmbed ,
82- } from "./miniapp" ;
83- import hljs , { whenHighlightReady } from "./lazy-hljs" ;
8472import { deepLinkPath , UI_BASE } from "./deep-link" ;
8573import type { ChatSurface , ConvCtx } from "./conv-types" ;
8674import { errMessage , swallow } from "../../chassis/src/errors" ;
@@ -129,53 +117,11 @@ interface SettledRowKey {
129117 approvalDecision : unknown ;
130118 sendFailure : unknown ;
131119 forkable : boolean ;
132- miniappKey : string ;
133120 tpl : TemplateResult | typeof nothing ;
134121}
135122const settledRowCache = new WeakMap < object , SettledRowKey > ( ) ;
136123const connectedConnectors = new Set < string > ( ) ;
137- const miniappPaneByUrl = new Map < string , "play" | "code" > ( ) ;
138- const miniappSourceByUrl = new Map < string , string > ( ) ;
139- const miniappBootByPath = new Map < string , { ok : boolean ; error ?: string } > ( ) ;
140- const miniappBootTimerByPath = new Map < string , number > ( ) ;
141124const redrawHooks = new Set < ( ) => void > ( ) ;
142-
143- function miniappPathOf ( src : string ) : string {
144- try {
145- return new URL ( src , location . origin ) . pathname ;
146- } catch {
147- return src ;
148- }
149- }
150-
151- function noteMiniappBoot ( path : string , boot : { ok : boolean ; error ?: string } ) : void {
152- if ( miniappBootByPath . get ( path ) ?. ok && boot . ok ) return ;
153- miniappBootByPath . set ( path , boot ) ;
154- const timer = miniappBootTimerByPath . get ( path ) ;
155- if ( timer !== undefined ) window . clearTimeout ( timer ) ;
156- miniappBootTimerByPath . delete ( path ) ;
157- for ( const hook of redrawHooks ) hook ( ) ;
158- }
159-
160- window . addEventListener ( "message" , ( event ) => {
161- const data = event . data as { source ?: string ; path ?: string ; ok ?: boolean ; error ?: string } | null ;
162- if ( ! data || data . source !== "qm-miniapp" || typeof data . path !== "string" ) return ;
163- noteMiniappBoot ( data . path , {
164- ok : Boolean ( data . ok ) ,
165- ...( typeof data . error === "string" && data . error ? { error : data . error } : { } ) ,
166- } ) ;
167- } ) ;
168-
169- function armMiniappBoot ( src : string ) : void {
170- const path = miniappPathOf ( src ) ;
171- if ( miniappBootByPath . has ( path ) || miniappBootTimerByPath . has ( path ) ) return ;
172- miniappBootTimerByPath . set (
173- path ,
174- window . setTimeout ( ( ) => {
175- if ( ! miniappBootByPath . has ( path ) ) noteMiniappBoot ( path , { ok : true } ) ;
176- } , 1500 ) ,
177- ) ;
178- }
179125let proactiveOpenerStarted = false ;
180126
181127export const sleep = ( ms : number ) : Promise < void > => new Promise ( ( r ) => setTimeout ( r , ms ) ) ;
@@ -563,13 +509,8 @@ export function createChatSurface(
563509 if ( chatState . agent ) drawActiveChat ( ) ;
564510 }
565511
566- function redrawForMiniapp ( ) : void {
567- redrawTranscript ( ) ;
568- }
569-
570512 function dispose ( ) : void {
571513 redrawHooks . delete ( redrawForConnector ) ;
572- redrawHooks . delete ( redrawForMiniapp ) ;
573514 teardownActiveChat ( ) ;
574515 }
575516
@@ -1296,13 +1237,6 @@ export function createChatSurface(
12961237 ( ! work || ( ( work . status === "complete" || work . status === "failed" ) && ! work . pendingApprovals ?. length ) ) ;
12971238 if ( ! cacheable ) return chatMessage ( message , index , isStreaming ) ;
12981239 const forkable = Boolean ( chatState . threadRef && chatState . sessionId && chatState . agent ) ;
1299- const miniappKey = miniappsIn ( messageText ( message ) )
1300- . map ( ( app ) => {
1301- const src = miniappFrameSrc ( app . url , withBase , currentMiniappTheme ( ) ) ;
1302- const boot = miniappBootByPath . get ( miniappPathOf ( src ) ) ;
1303- return `${ app . url } :${ miniappPaneByUrl . get ( app . url ) ?? "play" } :${ miniappSourceByUrl . get ( app . url ) ?? "" } :${ boot ? `${ boot . ok } :${ boot . error ?? "" } ` : "pending" } ` ;
1304- } )
1305- . join ( "\n" ) ;
13061240 const hit = settledRowCache . get ( message as object ) ;
13071241 if (
13081242 hit &&
@@ -1315,8 +1249,7 @@ export function createChatSurface(
13151249 hit . errorMessage === msg . errorMessage &&
13161250 hit . approvalDecision === msg . approvalDecision &&
13171251 hit . sendFailure === msg . sendFailure &&
1318- hit . forkable === forkable &&
1319- hit . miniappKey === miniappKey
1252+ hit . forkable === forkable
13201253 ) {
13211254 return hit . tpl ;
13221255 }
@@ -1332,7 +1265,6 @@ export function createChatSurface(
13321265 approvalDecision : msg . approvalDecision ,
13331266 sendFailure : msg . sendFailure ,
13341267 forkable,
1335- miniappKey,
13361268 tpl,
13371269 } ) ;
13381270 return tpl ;
@@ -1525,112 +1457,19 @@ export function createChatSurface(
15251457 </ a > ` ;
15261458 }
15271459
1528- function loadMiniappSource ( url : string , sourceSrc : string ) : void {
1529- if ( miniappSourceByUrl . has ( url ) ) return ;
1530- miniappSourceByUrl . set ( url , "" ) ;
1531- void fetch ( sourceSrc , { cache : "reload" } )
1532- . then ( async ( r ) => {
1533- miniappSourceByUrl . set ( url , r . ok ? await r . text ( ) : "Couldn't load the source." ) ;
1534- redrawTranscript ( ) ;
1535- } )
1536- . catch ( ( ) => {
1537- miniappSourceByUrl . set ( url , "Couldn't load the source." ) ;
1538- redrawTranscript ( ) ;
1539- } ) ;
1540- }
1541-
1542- function miniappSourceView ( source : string | undefined ) : TemplateResult {
1543- if ( ! source ) return html `< pre class ="miniapp-source " tabindex ="0 "> Loading source…</ pre > ` ;
1544- const formatted = formatMiniappHtml ( source ) ;
1545- if ( ! hljs . getLanguage ( "html" ) && ! hljs . getLanguage ( "xml" ) ) {
1546- void whenHighlightReady ( ) . then ( ( ) => redrawTranscript ( ) ) ;
1547- }
1548- return html `< pre class ="miniapp-source " tabindex ="0 ">
1549- ${ unsafeHTML ( hljs . highlight ( formatted , { language : "html" } ) . value ) } </ pre > `;
1550- }
1551-
1552- function miniappBootState (
1553- pane : "play" | "code" ,
1554- boot : { ok : boolean ; error ?: string } | undefined ,
1555- ) : TemplateResult | typeof nothing {
1556- if ( pane !== "play" ) return nothing ;
1557- if ( ! boot ) return html `< div class ="miniapp-boot " role ="status "> Starting…</ div > ` ;
1558- if ( ! boot . ok )
1559- return html `< div class ="miniapp-boot err " role ="alert "> ${ boot . error || "Playground hit an error." } </ div > ` ;
1560- return nothing ;
1561- }
1562-
1563- function miniappCard ( app : MiniappEmbed ) : TemplateResult {
1564- const src = miniappFrameSrc ( app . url , withBase , currentMiniappTheme ( ) ) ;
1565- const sourceSrc = miniappSourceSrc ( src ) ;
1566- const pane = miniappPaneByUrl . get ( app . url ) ?? "play" ;
1567- if ( pane === "code" ) loadMiniappSource ( app . url , sourceSrc ) ;
1568- const source = miniappSourceByUrl . get ( app . url ) ;
1569- const path = miniappPathOf ( src ) ;
1570- if ( pane === "play" ) armMiniappBoot ( src ) ;
1571- const boot = miniappBootByPath . get ( path ) ;
1572- return html `< div class ="miniapp-card ">
1573- < header class ="miniapp-card-bar ">
1574- < span class ="miniapp-card-icon "> ${ icon ( Files , 16 ) } </ span >
1575- < strong class ="miniapp-card-title "> ${ app . title } </ strong >
1576- < nav class ="miniapp-tabs " aria-label ="Playground views ">
1577- < button
1578- class ="miniapp-tab ${ pane === "play" ? "on" : "" } "
1579- type ="button "
1580- aria-pressed =${ pane === "play" }
1581- @click =${ ( ) => {
1582- miniappPaneByUrl . set ( app . url , "play" ) ;
1583- redrawTranscript ( ) ;
1584- } }
1585- >
1586- Play
1587- </ button >
1588- < button
1589- class ="miniapp-tab ${ pane === "code" ? "on" : "" } "
1590- type ="button "
1591- aria-pressed =${ pane === "code" }
1592- @click =${ ( ) => {
1593- miniappPaneByUrl . set ( app . url , "code" ) ;
1594- loadMiniappSource ( app . url , sourceSrc ) ;
1595- redrawTranscript ( ) ;
1596- } }
1597- >
1598- ${ icon ( Code2 , 13 ) } Code
1599- </ button >
1600- </ nav >
1601- < a class ="miniapp-card-open " href =${ src } target ="_blank" rel="noreferrer" title="Open in a new tab"
1602- > ${ icon ( Maximize2 , 14 ) } Open</ a
1603- >
1604- </ header >
1605- < div class ="miniapp-stage ">
1606- < iframe
1607- class ="miniapp-frame ${ pane === "code" ? "is-hidden" : "" } "
1608- src =${ src }
1609- title =${ app . title }
1610- sandbox="allow-scripts allow-forms allow-pointer-lock allow-modals allow-popups"
1611- referrerpolicy="no-referrer"
1612- > </ iframe >
1613- ${ miniappBootState ( pane , boot ) } ${ pane === "code" ? miniappSourceView ( source ) : nothing }
1614- </ div >
1615- </ div > ` ;
1616- }
1617-
16181460 function assistantContent ( message : AssistantMessage , isStreaming = false , hasWork = false ) : TemplateResult [ ] {
16191461 const parts : TemplateResult [ ] = [ ] ;
16201462 for ( const chunk of message . content ) {
16211463 if ( chunk . type === "text" && chunk . text . trim ( ) ) {
16221464 const links = connectorLinksIn ( chunk . text , location . origin ) ;
1623- const apps = miniappsIn ( chunk . text ) ;
1624- let body = stripMiniappDirectives ( chunk . text ) ;
1625- if ( links . length ) body = stripConnectorLinks ( body ) ;
1465+ const body = links . length ? stripConnectorLinks ( chunk . text ) : chunk . text ;
16261466 if ( body . trim ( ) )
16271467 parts . push (
16281468 html `< div class ="streaming-text ${ isStreaming ? "live-stream" : "" } ">
16291469 ${ isStreaming ? streamingMarkdown ( body ) : markdown ( body ) }
16301470 </ div > ` ,
16311471 ) ;
16321472 for ( const link of links ) parts . push ( connectorWidget ( link ) ) ;
1633- if ( ! isStreaming ) for ( const app of apps ) parts . push ( miniappCard ( app ) ) ;
16341473 }
16351474 if ( chunk . type === "thinking" && chunk . thinking . trim ( ) ) {
16361475 parts . push (
@@ -2460,7 +2299,6 @@ ${unsafeHTML(hljs.highlight(formatted, { language: "html" }).value)}</pre>`;
24602299 }
24612300
24622301 redrawHooks . add ( redrawForConnector ) ;
2463- redrawHooks . add ( redrawForMiniapp ) ;
24642302
24652303 return {
24662304 state : chatState ,
0 commit comments