Skip to content

Commit 718aedb

Browse files
authored
Merge branch 'main' into blove/recursing-chaplygin-f20d49
2 parents b9bf841 + bd17dc6 commit 718aedb

80 files changed

Lines changed: 3415 additions & 251 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,14 @@ jobs:
809809
cache: npm
810810
- run: npm ci
811811
- name: Build and assemble canonical demo
812+
env:
813+
# Baked into the SPA bundle by inject-env at build time (assemble-demo.ts
814+
# runs `nx build examples-chat-angular`, whose build target dependsOn
815+
# inject-env). Without the key the App-mode map toggle is disabled in
816+
# prod. The key ships in the public bundle (normal for Maps JS) — restrict
817+
# it by HTTP referrer in the Google Cloud console. The Map ID is not a secret.
818+
GOOGLE_MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }}
819+
GOOGLE_MAPS_MAP_ID: 86d464ea7d5306034fe2a254
812820
run: npx tsx scripts/assemble-demo.ts
813821
- name: Deploy canonical demo to Vercel (production)
814822
working-directory: deploy/demo

apps/website/content/docs/chat/api/api-docs.json

Lines changed: 243 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,19 +1614,31 @@
16141614
"optional": false
16151615
},
16161616
{
1617-
"name": "monoColor",
1618-
"type": "Signal<string>",
1617+
"name": "published",
1618+
"type": "Signal<string | null>",
16191619
"description": "",
16201620
"optional": false
16211621
},
16221622
{
1623-
"name": "monogram",
1624-
"type": "Signal<string>",
1623+
"name": "sourceIcon",
1624+
"type": "Signal<CitationTypeIcon | null>",
16251625
"description": "",
16261626
"optional": false
16271627
},
16281628
{
1629-
"name": "published",
1629+
"name": "sourceIconUrl",
1630+
"type": "Signal<string | null>",
1631+
"description": "",
1632+
"optional": false
1633+
},
1634+
{
1635+
"name": "sourceMonoColor",
1636+
"type": "Signal<string | null>",
1637+
"description": "",
1638+
"optional": false
1639+
},
1640+
{
1641+
"name": "sourceMonogram",
16301642
"type": "Signal<string | null>",
16311643
"description": "",
16321644
"optional": false
@@ -1636,9 +1648,29 @@
16361648
"type": "Signal<string | null>",
16371649
"description": "",
16381650
"optional": false
1651+
},
1652+
{
1653+
"name": "typeTone",
1654+
"type": "Signal<CitationTypeIcon>",
1655+
"description": "",
1656+
"optional": false
16391657
}
16401658
],
1641-
"methods": []
1659+
"methods": [
1660+
{
1661+
"name": "isTypeTone",
1662+
"signature": "isTypeTone(tone: CitationTypeIcon): boolean",
1663+
"description": "",
1664+
"params": [
1665+
{
1666+
"name": "tone",
1667+
"type": "CitationTypeIcon",
1668+
"description": "",
1669+
"optional": false
1670+
}
1671+
]
1672+
}
1673+
]
16421674
},
16431675
{
16441676
"name": "ChatCitationsCardComponent",
@@ -1660,14 +1692,26 @@
16601692
"optional": false
16611693
},
16621694
{
1663-
"name": "monoColor",
1664-
"type": "Signal<string>",
1695+
"name": "sourceIcon",
1696+
"type": "Signal<CitationTypeIcon | null>",
16651697
"description": "",
16661698
"optional": false
16671699
},
16681700
{
1669-
"name": "monogram",
1670-
"type": "Signal<string>",
1701+
"name": "sourceIconUrl",
1702+
"type": "Signal<string | null>",
1703+
"description": "",
1704+
"optional": false
1705+
},
1706+
{
1707+
"name": "sourceMonoColor",
1708+
"type": "Signal<string | null>",
1709+
"description": "",
1710+
"optional": false
1711+
},
1712+
{
1713+
"name": "sourceMonogram",
1714+
"type": "Signal<string | null>",
16711715
"description": "",
16721716
"optional": false
16731717
},
@@ -1682,9 +1726,29 @@
16821726
"type": "Signal<string | null>",
16831727
"description": "",
16841728
"optional": false
1729+
},
1730+
{
1731+
"name": "typeTone",
1732+
"type": "Signal<CitationTypeIcon>",
1733+
"description": "",
1734+
"optional": false
16851735
}
16861736
],
1687-
"methods": []
1737+
"methods": [
1738+
{
1739+
"name": "isTypeTone",
1740+
"signature": "isTypeTone(tone: CitationTypeIcon): boolean",
1741+
"description": "",
1742+
"params": [
1743+
{
1744+
"name": "tone",
1745+
"type": "CitationTypeIcon",
1746+
"description": "",
1747+
"optional": false
1748+
}
1749+
]
1750+
}
1751+
]
16881752
},
16891753
{
16901754
"name": "ChatCitationsComponent",
@@ -6508,6 +6572,122 @@
65086572
],
65096573
"examples": []
65106574
},
6575+
{
6576+
"name": "CitationImageVisual",
6577+
"kind": "interface",
6578+
"description": "",
6579+
"properties": [
6580+
{
6581+
"name": "iconUrl",
6582+
"type": "string",
6583+
"description": "",
6584+
"optional": false
6585+
},
6586+
{
6587+
"name": "kind",
6588+
"type": "\"image\"",
6589+
"description": "",
6590+
"optional": false
6591+
}
6592+
],
6593+
"examples": []
6594+
},
6595+
{
6596+
"name": "CitationMonogramVisual",
6597+
"kind": "interface",
6598+
"description": "",
6599+
"properties": [
6600+
{
6601+
"name": "color",
6602+
"type": "string",
6603+
"description": "",
6604+
"optional": false
6605+
},
6606+
{
6607+
"name": "kind",
6608+
"type": "\"monogram\"",
6609+
"description": "",
6610+
"optional": false
6611+
},
6612+
{
6613+
"name": "monogram",
6614+
"type": "string",
6615+
"description": "",
6616+
"optional": false
6617+
}
6618+
],
6619+
"examples": []
6620+
},
6621+
{
6622+
"name": "CitationTypeIconVisual",
6623+
"kind": "interface",
6624+
"description": "",
6625+
"properties": [
6626+
{
6627+
"name": "icon",
6628+
"type": "CitationTypeIcon",
6629+
"description": "",
6630+
"optional": false
6631+
},
6632+
{
6633+
"name": "kind",
6634+
"type": "\"type-icon\"",
6635+
"description": "",
6636+
"optional": false
6637+
},
6638+
{
6639+
"name": "label",
6640+
"type": "string | null",
6641+
"description": "",
6642+
"optional": false
6643+
},
6644+
{
6645+
"name": "tone",
6646+
"type": "CitationTypeIcon",
6647+
"description": "",
6648+
"optional": false
6649+
}
6650+
],
6651+
"examples": []
6652+
},
6653+
{
6654+
"name": "CitationTypeMeta",
6655+
"kind": "interface",
6656+
"description": "",
6657+
"properties": [
6658+
{
6659+
"name": "icon",
6660+
"type": "CitationTypeIcon",
6661+
"description": "",
6662+
"optional": false
6663+
},
6664+
{
6665+
"name": "isKnown",
6666+
"type": "boolean",
6667+
"description": "",
6668+
"optional": false
6669+
},
6670+
{
6671+
"name": "label",
6672+
"type": "string | null",
6673+
"description": "",
6674+
"optional": false
6675+
},
6676+
{
6677+
"name": "tone",
6678+
"type": "CitationTypeIcon",
6679+
"description": "",
6680+
"optional": false
6681+
},
6682+
{
6683+
"name": "type",
6684+
"type": "string",
6685+
"description": "",
6686+
"optional": false
6687+
}
6688+
],
6689+
"examples": []
6690+
},
65116691
{
65126692
"name": "ClientToolsCapability",
65136693
"kind": "interface",
@@ -7732,6 +7912,20 @@
77327912
"signature": "\"expanded\" | \"collapsed\" | \"drawer\"",
77337913
"examples": []
77347914
},
7915+
{
7916+
"name": "CitationSourceVisual",
7917+
"kind": "type",
7918+
"description": "",
7919+
"signature": "CitationImageVisual | CitationTypeIconVisual | CitationMonogramVisual",
7920+
"examples": []
7921+
},
7922+
{
7923+
"name": "CitationTypeIcon",
7924+
"kind": "type",
7925+
"description": "",
7926+
"signature": "\"web\" | \"file\" | \"app\" | \"memory\" | \"generic\"",
7927+
"examples": []
7928+
},
77357929
{
77367930
"name": "ClientToolDef",
77377931
"kind": "type",
@@ -8005,6 +8199,25 @@
80058199
},
80068200
"examples": []
80078201
},
8202+
{
8203+
"name": "citationSourceVisual",
8204+
"kind": "function",
8205+
"description": "Choose the visual source marker for a citation: provider image, type icon, or monogram.",
8206+
"signature": "citationSourceVisual(c: Citation): CitationSourceVisual",
8207+
"params": [
8208+
{
8209+
"name": "c",
8210+
"type": "Citation",
8211+
"description": "",
8212+
"optional": false
8213+
}
8214+
],
8215+
"returns": {
8216+
"type": "CitationSourceVisual",
8217+
"description": ""
8218+
},
8219+
"examples": []
8220+
},
80088221
{
80098222
"name": "citationTypeLabel",
80108223
"kind": "function",
@@ -8024,6 +8237,25 @@
80248237
},
80258238
"examples": []
80268239
},
8240+
{
8241+
"name": "citationTypeMeta",
8242+
"kind": "function",
8243+
"description": "Derive normalized source-type metadata for badges, icons, and tone tokens.",
8244+
"signature": "citationTypeMeta(c: Citation): CitationTypeMeta",
8245+
"params": [
8246+
{
8247+
"name": "c",
8248+
"type": "Citation",
8249+
"description": "",
8250+
"optional": false
8251+
}
8252+
],
8253+
"returns": {
8254+
"type": "CitationTypeMeta",
8255+
"description": ""
8256+
},
8257+
"examples": []
8258+
},
80278259
{
80288260
"name": "createA2uiSurfaceStore",
80298261
"kind": "function",

apps/website/content/docs/chat/concepts/message-model.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,17 @@ interface Citation {
138138
title?: string;
139139
url?: string;
140140
snippet?: string;
141+
sourceType?: string; // 'web' | 'file' | 'app' | 'memory' | custom
142+
iconUrl?: string; // provider-supplied favicon/logo URL or data URI
143+
publishedAt?: string | number | Date;
141144
extra?: Record<string, unknown>; // provider-specific extras
142145
}
143146
```
144147

145148
`@threadplane/langgraph` exports `extractCitations()` for advanced adapters that need to normalize nonstandard citation payloads. Chat markdown views can render citation markers against the message citation list.
146149

150+
Citation display derives a type badge from `sourceType`; when it is absent and `url` is present, the source is treated as `web`. `iconUrl` takes precedence over generated source icons and monograms.
151+
147152
The resolve path from a `[^id]` marker to a rendered citation runs through `CitationsResolverService` (exported from `@threadplane/chat`). A custom citation renderer provides the service, sets the current message, then calls `lookup(refId)` — which returns a reactive `Signal<ResolvedCitation | null>` matching the marker id against `message.citations` (falling back to inline markdown definitions):
148153

149154
```ts

cockpit/chat/input/angular/src/app/input.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import { injectAgent } from '@threadplane/langgraph';
3333
ExampleChatLayoutComponent,
3434
],
3535
template: `
36-
<example-chat-layout sidebarWidth="w-72">
36+
<example-chat-layout sidebarWidth="18rem">
3737
<div main class="flex-1 flex flex-col min-w-0">
3838
<header class="px-4 py-3 border-b" style="border-color: var(--tplane-chat-separator); background: var(--tplane-chat-bg);">
3939
<h1 class="text-sm font-semibold" style="color: var(--tplane-chat-text);">Chat Input Demo</h1>

cockpit/chat/interrupts/angular/src/app/interrupts.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ const SUGGESTIONS = [
5050
ExampleChatLayoutComponent,
5151
],
5252
template: `
53-
<example-chat-layout sidebarWidth="w-80">
53+
<example-chat-layout sidebarWidth="20rem">
5454
<chat main [agent]="agent" class="flex-1 min-w-0">
5555
<div chatWelcomeSuggestions>
5656
@for (s of suggestions; track s.value) {

cockpit/chat/messages/angular/src/app/messages.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import { MESSAGES_AGENT, type MessagesState } from './agent-ref';
3939
ExampleChatLayoutComponent,
4040
],
4141
template: `
42-
<example-chat-layout sidebarWidth="w-72">
42+
<example-chat-layout sidebarWidth="18rem">
4343
<div main class="flex-1 flex flex-col min-w-0">
4444
<header class="px-4 py-3 border-b" style="border-color: var(--tplane-chat-separator); background: var(--tplane-chat-bg);">
4545
<h1 class="text-sm font-semibold" style="color: var(--tplane-chat-text);">Chat Messages Primitives</h1>

cockpit/chat/subagents/angular/src/app/subagents.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const SUGGESTIONS = [
3535
ExampleChatLayoutComponent,
3636
],
3737
template: `
38-
<example-chat-layout sidebarWidth="w-80">
38+
<example-chat-layout sidebarWidth="20rem">
3939
<chat main [agent]="agent" class="flex-1 min-w-0">
4040
<div chatWelcomeSuggestions>
4141
@for (s of suggestions; track s.value) {

0 commit comments

Comments
 (0)