Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## Unreleased

- Catalogue re-exported from site commit 1072362: the London 2026 recordings are public. "Will talks be recorded?" now answers "Yes. Recordings are public and published on https://agentengineering.world/london-2026/videos as they become available, starting with the welcome video.", and the day guide's photography and content section says the same. The previous wording limited recordings to ticket holders.
- Plain-English questions such as "Will talks be recorded?" and "Are the talks recorded?" now return that published answer instead of a talk-topic miss.
- Catalogue re-exported from site commit 4e34c4b: the Harness Engineering San Francisco video is an event recap, not a recording. It is now `sf-harness-engineering-2026-recap` (`/gallery/sf-harness-engineering-2026-recap`), titled "Harness Engineering San Francisco: event recap", with the summary "Recap of our Harness Engineering evening in San Francisco, attended by 300+ members."
- Event recaps are their own kind, `event-recap`, in `agenteng gallery`, `agenteng recordings` and talk payloads, shown as "Event recap". The four Harness Engineering San Francisco sessions in `agenteng talks` no longer point to it as their recording. `agenteng gallery sf-harness-engineering-2026-full-event` still resolves to the recap.

## 0.0.25 - 2026-10-18

- Catalogue re-exported from site commit e968fc9, which moves the London 2026 conference under `/london-2026`. Sources and answers now link to `/london-2026/speakers`, `/london-2026/agenda`, `/london-2026/guide`, `/london-2026#faq` and `/london-2026` (formerly `/#venue`, `/#agenda` and `/#tickets`). London's post-event behaviour is unchanged, and San Francisco stays upcoming.
Expand Down
4 changes: 2 additions & 2 deletions docs/COMMANDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ agenteng gallery --city London
agenteng gallery london-2026-welcome
```

The primary command for videos. Order follows [/gallery](https://agentengineering.world/gallery): the [London 2026 recordings](https://agentengineering.world/london-2026/videos) (the welcome video `iTV8VSrVJEk`, then the 10 talks marked "Recording coming soon"), then the Harness Engineering San Francisco full-event recording. Each row carries `slug`, `gallery` (`london`, `san-francisco` or `a2a`), `status` (`recorded`, `recording-coming-soon` or `upcoming`), `status_label`, `youtube_id` and `video_url` when published, and `talk_url` (`/gallery/<slug>`). Transcripts are included only when the website publishes one; none are published today. A2A talks keep their AI-generated label and the A2A disclaimer; `agenteng a2a-talks` remains the dedicated view. Over MCP, A2A and REST use `{"operation":"gallery"}` with optional `city`, `event_id`, `topic`, `query`, `speaker_id` and `include_a2a`, or `{"operation":"talk","session_id":"<slug>"}` for one item.
The primary command for videos. Order follows [/gallery](https://agentengineering.world/gallery): the [London 2026 recordings](https://agentengineering.world/london-2026/videos) (the welcome video `iTV8VSrVJEk`, then the 10 talks marked "Recording coming soon"), then the Harness Engineering San Francisco event recap (kind `event-recap`, a short recap of the evening, not a talk recording; the old slug `sf-harness-engineering-2026-full-event` still resolves). Each row carries `slug`, `gallery_kind` (`talk`, `event-recording`, `event-recap` or `a2a`), `summary` when the site publishes one, `gallery` (`london`, `san-francisco` or `a2a`), `status` (`recorded`, `recording-coming-soon` or `upcoming`), `status_label`, `youtube_id` and `video_url` when published, and `talk_url` (`/gallery/<slug>`). Transcripts are included only when the website publishes one; none are published today. A2A talks keep their AI-generated label and the A2A disclaimer; `agenteng a2a-talks` remains the dedicated view. Over MCP, A2A and REST use `{"operation":"gallery"}` with optional `city`, `event_id`, `topic`, `query`, `speaker_id` and `include_a2a`, or `{"operation":"talk","session_id":"<slug>"}` for one item.

### agenteng talks

Expand Down Expand Up @@ -369,7 +369,7 @@ agenteng recordings [OPTIONS]
agenteng recordings --city London
```

Lists the [London 2026 recordings page](https://agentengineering.world/london-2026/videos), event recordings and gallery recordings with a published YouTube video (the London 2026 welcome video and the Harness Engineering San Francisco full event), without duplicates. While London 2026 talk recordings are pending the answer says so and points to `agenteng gallery --city London`. A2A videos are listed by `agenteng a2a-talks`, not here.
Lists the [London 2026 recordings page](https://agentengineering.world/london-2026/videos), event recordings and gallery recordings with a published YouTube video (the London 2026 welcome video, and the Harness Engineering San Francisco event recap, marked `"kind": "event-recap"`), without duplicates. While London 2026 talk recordings are pending the answer says so and points to `agenteng gallery --city London`. A2A videos are listed by `agenteng a2a-talks`, not here.

### agenteng a2a-talks

Expand Down
2 changes: 1 addition & 1 deletion docs/SITE-SYNC.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ Pages mirrored:

Data files read by `scripts/export-website.mjs`:

- `src/data/talks.ts`: exports `londonVideos` (the London welcome recording, then the 10 London talks), `sfGallery` (the Harness Engineering San Francisco full-event recording) and `talks` (both, then the A2A talks). `/gallery` shows `londonVideos` and `sfGallery`. Each exported row has a `gallery` tab (`london`, `san-francisco` or `a2a`), slug, title, kind, city, event, speaker, topics, `youtube_id`, `transcript`, status, AI-generated flag and its `/gallery/<slug>` URL, with one source each. `talks.ts` builds its rows from other data, so the exporter rebuilds them from the same literals (the `londonWelcome` and `sfRecordings` literals, agenda, speakers, `sf-code-engineering.ts` and `agentToAgent.ts`) and fails if the exports, the Gallery page or the mapping change, or if London or Code Engineering talks start publishing a YouTube ID or transcript, so a newly published recording is mirrored deliberately. No transcripts are published today, so none are exported. A2A rows use the `a2a-talks` source kind, so general search leaves them out.
- `src/data/talks.ts`: exports `londonVideos` (the London welcome recording, then the 10 London talks), `sfGallery` (the Harness Engineering San Francisco event recap, kind `event-recap`, slug `sf-harness-engineering-2026-recap`, with the site's `summary`; the site redirects the old `/gallery/sf-harness-engineering-2026-full-event` and `agenteng gallery` still accepts the old slug) and `talks` (both, then the A2A talks). `/gallery` shows `londonVideos` and `sfGallery`. Event recaps are their own kind: they are never labelled as talk recordings, and the Harness Engineering San Francisco sessions do not point to the recap as their recording. Each exported row has a `gallery` tab (`london`, `san-francisco` or `a2a`), slug, title, kind, city, event, speaker, topics, `youtube_id`, `transcript`, status, AI-generated flag and its `/gallery/<slug>` URL, with one source each. `talks.ts` builds its rows from other data, so the exporter rebuilds them from the same literals (the `londonWelcome` and `sfRecordings` literals, agenda, speakers, `sf-code-engineering.ts` and `agentToAgent.ts`) and fails if the exports, the Gallery page or the mapping change, or if London or Code Engineering talks start publishing a YouTube ID or transcript, so a newly published recording is mirrored deliberately. No transcripts are published today, so none are exported. A2A rows use the `a2a-talks` source kind, so general search leaves them out.
- `codeEngineeringTalks` in `talks.ts` is kept for /san-francisco only: the four Code Engineering San Francisco talks have no gallery page, so they are exported with `gallery: null` and link to `/san-francisco`.
- `src/data/sf-code-engineering.ts`: roles, companies and links for the Code Engineering San Francisco (27 October 2026) speakers, checked against the SanFrancisco page roster.
- `src/data/events.ts`: next and previous editions (`site_links.next_event` is Agent Engineering San Francisco, April 2027, `/san-francisco`; `site_links.previous_event` is London 2026, `/london-2026`), plus each event's `page_url`. `site_links` also holds `/gallery` and `/london-2026/videos`. The April 2027 conference is announced without a date or venue, so it is a link labelled "coming April 2027", not a catalogue event. The discovery prompt that used to read "Find the next Agent Engineering Conference in London" now follows `site_links.next_event`: "What is the next Agent Engineering event in San Francisco?", answered with the next published San Francisco event and "Agent Engineering San Francisco is coming April 2027".
Expand Down
3 changes: 2 additions & 1 deletion scripts/export-website.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ const eventIdFor = id => id === 'london-2026' ? london : id;
const literalTalk = r => ({slug: r.slug, title: r.title, kind: r.kind, city: r.city, event_id: eventIdFor(r.eventId),
event_name: r.eventName, event_url: site + r.eventHref, date: r.date, speaker: null, topics: r.topics,
youtube_id: r.youtubeId ?? null, transcript: r.transcript ? clean(r.transcript) : null,
summary: r.summary ? clean(r.summary) : null,
ai_generated: false, status: r.status, session_id: null});
const talks = [];
const welcome = constant('londonWelcome');
Expand Down Expand Up @@ -560,7 +561,7 @@ if (new Set(talks.map(t => t.slug)).size !== talks.length) throw new Error('Dupl
for (const t of talks) {
t.url = t.gallery ? site + '/gallery/' + t.slug : site + '/san-francisco';
t.source_ids = [source('talk-' + t.slug, t.url, [t.title, t.speaker ? `${t.speaker.name}, ${t.speaker.role} at ${t.speaker.company}` : null,
t.event_name, t.ai_generated ? 'AI-generated video.' : null, t.status].filter(Boolean).join('\n'), t.event_id, t.kind === 'a2a' ? 'a2a-talks' : 'talk')];
t.summary || null, t.event_name, t.ai_generated ? 'AI-generated video.' : null, t.status].filter(Boolean).join('\n'), t.event_id, t.kind === 'a2a' ? 'a2a-talks' : 'talk')];
}
source('london-videos', londonVideosPage, 'Agent Engineering London 2026 recordings: ' + welcome.title +
' (https://www.youtube.com/watch?v=' + welcome.youtubeId + '). Talk recordings coming soon.', london, 'recordings');
Expand Down
4 changes: 2 additions & 2 deletions src/agenteng/a2a.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ def agent_card(service):
description="The website video gallery (gallery; optional city, event_id, topic, "
"query and speaker_id), mirroring /gallery: the AgentEng London 2026 recordings "
"from /london-2026/videos (the welcome video, then talks marked "
"recording-coming-soon) and the Harness Engineering San Francisco full-event "
"recording, with YouTube IDs when published and /gallery/<slug> links. One item "
"recording-coming-soon) and the Harness Engineering San Francisco event recap "
"video, with YouTube IDs when published and /gallery/<slug> links. One item "
"by slug: talk with session_id set to the slug. A2A talks are added only with "
"include_a2a, listed last and labelled AI-generated. Model-free.",
tags=["gallery", "videos", "recordings", "london-2026", "san-francisco"],
Expand Down
4 changes: 4 additions & 0 deletions src/agenteng/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ def resolve_talk(ctx, identifier: str, event_id: str | None = None):
``agenteng-london-2026-14`` share most tokens with other talks.
"""

from .service import OLD_GALLERY_SLUGS

identifier = OLD_GALLERY_SLUGS.get(identifier, identifier)

def talk_rows(query: str) -> list[dict]:
rows: list[dict] = []
for operation in ("talks", "gallery"):
Expand Down
34 changes: 18 additions & 16 deletions src/agenteng/data/catalogue.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"schema_version": 1,
"version": "website-b4161284575e",
"published_at": "2026-10-18T10:42:35.592Z",
"source_commit": "8cd5a6a51e815cff0de3dab4874508d9609393b1",
"source_hash": "b4161284575ee9de4034719820d5f2bdb674fb8f443c49ae1892d12200606939",
"version": "website-d3c49871fc80",
"published_at": "2026-10-18T11:09:19.364Z",
"source_commit": "4e34c4b4257525dc18d6ab724cc37e2597251af5",
"source_hash": "d3c49871fc80cc4b0cb61392e3bcec13f262466d3d7d2c7e0b49cde81429d859",
"events": [
{
"id": "agenteng-london-2026",
Expand Down Expand Up @@ -1278,7 +1278,7 @@
{
"id": "faq-15",
"question": "Will talks be recorded?",
"answer": "Yes. Talks are recorded and shared with ticket holders after the day.",
"answer": "Yes. Recordings are public and published on https://agentengineering.world/london-2026/videos as they become available, starting with the welcome video.",
"event_id": "agenteng-london-2026",
"source_ids": [
"faq-15"
Expand Down Expand Up @@ -1590,7 +1590,7 @@
"id": "photography",
"title": "Photography and content",
"paragraphs": [
"There will be official photography and some official video recording.",
"There will be official photography and some official video recording. Recordings are public and published on https://agentengineering.world/london-2026/videos as they become available, starting with the welcome video.",
"The conference is not a content creation spot for marketing. Please don't film or create content involving other attendees or speakers without their consent."
],
"links": []
Expand Down Expand Up @@ -1841,6 +1841,7 @@
],
"youtube_id": "iTV8VSrVJEk",
"transcript": null,
"summary": null,
"ai_generated": false,
"status": "recorded",
"session_id": null,
Expand Down Expand Up @@ -2151,9 +2152,9 @@
]
},
{
"slug": "sf-harness-engineering-2026-full-event",
"title": "Harness Engineering: State of the Art in Agent Harnesses",
"kind": "event-recording",
"slug": "sf-harness-engineering-2026-recap",
"title": "Harness Engineering San Francisco: event recap",
"kind": "event-recap",
"city": "San Francisco",
"event_id": "sf-harness-engineering-2026",
"event_name": "Harness Engineering San Francisco",
Expand All @@ -2166,13 +2167,14 @@
],
"youtube_id": "AP1RRbXZhsE",
"transcript": null,
"summary": "Recap of our Harness Engineering evening in San Francisco, attended by 300+ members.",
"ai_generated": false,
"status": "recorded",
"session_id": null,
"gallery": "san-francisco",
"url": "https://agentengineering.world/gallery/sf-harness-engineering-2026-full-event",
"url": "https://agentengineering.world/gallery/sf-harness-engineering-2026-recap",
"source_ids": [
"talk-sf-harness-engineering-2026-full-event"
"talk-sf-harness-engineering-2026-recap"
]
},
{
Expand Down Expand Up @@ -3090,7 +3092,7 @@
{
"id": "faq-15",
"url": "https://agentengineering.world/london-2026#faq",
"text": "Will talks be recorded?\nYes. Talks are recorded and shared with ticket holders after the day.",
"text": "Will talks be recorded?\nYes. Recordings are public and published on https://agentengineering.world/london-2026/videos as they become available, starting with the welcome video.",
"event_id": "agenteng-london-2026",
"kind": "faq"
},
Expand Down Expand Up @@ -3286,7 +3288,7 @@
{
"id": "guide-photography",
"url": "https://agentengineering.world/london-2026/guide#photography",
"text": "Photography and content\nThere will be official photography and some official video recording.\nThe conference is not a content creation spot for marketing. Please don't film or create content involving other attendees or speakers without their consent.",
"text": "Photography and content\nThere will be official photography and some official video recording. Recordings are public and published on https://agentengineering.world/london-2026/videos as they become available, starting with the welcome video.\nThe conference is not a content creation spot for marketing. Please don't film or create content involving other attendees or speakers without their consent.",
"event_id": "agenteng-london-2026",
"kind": "guide"
},
Expand Down Expand Up @@ -3417,9 +3419,9 @@
"kind": "talk"
},
{
"id": "talk-sf-harness-engineering-2026-full-event",
"url": "https://agentengineering.world/gallery/sf-harness-engineering-2026-full-event",
"text": "Harness Engineering: State of the Art in Agent Harnesses\nHarness Engineering San Francisco\nrecorded",
"id": "talk-sf-harness-engineering-2026-recap",
"url": "https://agentengineering.world/gallery/sf-harness-engineering-2026-recap",
"text": "Harness Engineering San Francisco: event recap\nRecap of our Harness Engineering evening in San Francisco, attended by 300+ members.\nHarness Engineering San Francisco\nrecorded",
"event_id": "sf-harness-engineering-2026",
"kind": "talk"
},
Expand Down
3 changes: 2 additions & 1 deletion src/agenteng/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ class Talk(Model):

slug: str
title: str
kind: Literal["talk", "event-recording", "a2a"]
kind: Literal["talk", "event-recording", "event-recap", "a2a"]
city: str
event_id: str | None = None
event_name: str
Expand All @@ -354,6 +354,7 @@ class Talk(Model):
topics: list[str] = Field(default_factory=list)
youtube_id: str | None = None
transcript: str | None = None
summary: str | None = None
ai_generated: bool = False
status: Literal["upcoming", "recording-coming-soon", "recorded"]
session_id: str | None = None
Expand Down
20 changes: 18 additions & 2 deletions src/agenteng/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,9 @@ def _talk_body(talk: dict, *, include_title: bool = True) -> Text:
for p in (
"A2A talk" if kind == "a2a" else kind.replace("-", " "),
talk.get("event_name") if talk.get("slug") else None,
talk.get("status_label"),
None
if (talk.get("status_label") or "").casefold() == kind.replace("-", " ")
else talk.get("status_label"),
)
if p
)
Expand All @@ -304,6 +306,8 @@ def _talk_body(talk: dict, *, include_title: bool = True) -> Text:
title = talk.get("title") or talk.get("talk_title")
if title:
body.append(display_text(title) + "\n")
if talk.get("summary"):
body.append(display_text(talk["summary"]) + "\n")
if talk.get("speaker_name"):
meta = " · ".join(
p
Expand Down Expand Up @@ -344,6 +348,8 @@ def render_talks(console: Console, result: Result) -> None:
header = "A2A talk (AI-generated)" if talk.get("ai_generated") else "Talk"
if not talk.get("ai_generated") and talk.get("gallery_kind") == "event-recording":
header = "Recording"
elif talk.get("gallery_kind") == "event-recap":
header = "Event recap"
console.print(_panel(header, _talk_body(talk, include_title=True), border=VIOLET))
console.print(f"[ae.meta]{display_text(result.answer)}[/]")

Expand All @@ -353,7 +359,13 @@ def render_talk(console: Console, result: Result) -> None:
if not talk:
console.print(f"[ae.meta]{display_text(result.answer)}[/]")
return
console.print(_panel("Talk", _talk_body(talk, include_title=True), border=VIOLET))
kind = talk.get("gallery_kind")
header = (
"A2A talk (AI-generated)"
if talk.get("ai_generated")
else {"event-recap": "Event recap", "event-recording": "Recording"}.get(kind, "Talk")
)
console.print(_panel(header, _talk_body(talk, include_title=True), border=VIOLET))
console.print(f"[ae.meta]{display_text(result.answer)}[/]")


Expand Down Expand Up @@ -622,8 +634,12 @@ def render_recordings(console: Console, result: Result) -> None:
console.print(Text("Recordings", style="ae.title"))
for row in rows:
body = Text()
if row.get("kind") == "event-recap":
body.append("Event recap\n", style="ae.accent")
if row.get("event_id"):
body.append(f"Event: {row['event_id']}\n", style="ae.meta")
if row.get("summary"):
body.append(display_text(row["summary"]) + "\n")
if row.get("url"):
body.append(str(row["url"]), style=BLUE)
console.print(_panel(display_text(row.get("title")) or "Recording", body, border=VIOLET))
Expand Down
Loading
Loading