Release/1.11.0 - #722
Merged
Merged
Conversation
…5-spa-panel feat(memory): Memory Spaces SPA panel — list/detail/create/share/export (A5)
app-api owns the Memory Spaces CRUD surface (`/memory/spaces/*`) but its container environment only set MEMORY_SPACES_ENABLED — never the table or bucket names the service reads (DYNAMODB_MEMORY_SPACES_TABLE_NAME / S3_MEMORY_SPACES_BUCKET_NAME). Without them the repository falls back to the default "memory-spaces" table name, which doesn't exist, so every read throws a boto3 ResourceNotFoundException that the centralized handler maps to a 502 "Upstream service error." (inference-api already sets the identical trio, but per the service-boundary rule it isn't the one serving these routes.) Thread `refs.memorySpacesTable`/`.memorySpacesBucket` through AppApiSsmParams and emit both names next to the flag in buildAppApiEnvironment. Names are always wired (read lazily); only MEMORY_SPACES_ENABLED gates route mounting, so flipping the switch on later needs no env change. New unit test guards the wiring; tsc + 431 infra jest tests green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fold the lesson from the app-api env-wiring fix into the cdk-infrastructure skill so the next construct-author sees it while wiring, not after a 502. Adds a "Cross-Construct References" subsection: set a resource's name env var on every compute that reads it (one doesn't imply the other), the silent-502 failure mode (default-name fallback → ResourceNotFoundException → generic 502, invisible to synth/CI), and the env-map test guard + service-boundary caveat. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…s-app-api-env-wiring fix(memory): wire memory-spaces table/bucket names onto app-api
The safe, non-LLM slice of Workstream A6. `MemorySpaceService.consolidate`
(editor+) + `POST /memory/spaces/{id}/consolidate` → a `ConsolidationReport`.
Auto-fixes only storage hygiene: orphaned content-addressed objects — keys
under a space's prefix that no manifest entry or the index pointer references
(leaks from crashed/raced writes) — are GC'd (new `MemorySpaceStore.list_keys`
drives it). Everything that needs a judgment call is *reported, not mutated*:
- duplicate content across slugs (same content hash) — which slug survives is
semantic, so it's flagged, never auto-merged;
- dead `[[slug]]` wikilinks in MEMORY.md — reported; opt-in `stripDeadLinks`
unlinks them (they point nowhere) while preserving the surrounding prose;
- over-cap entry counts (`MEMORY_SPACE_INDEX_CAP`, default 200) — flagged, never
auto-evicted.
This deliberately does not merge/evict/rewrite durable memory — that's deferred
to the LLM consolidation pass (Workstream B era), which extends this exact
`consolidate()` seam once agentic writes create real duplication/staleness to
act on. On-demand only for now; scheduler/threshold auto-run and SPA surfacing
are follow-ups.
Tests: 8 service (healthy report, orphan GC + skip, dup-report-no-merge,
dead-link report + strip-keeps-prose, over-cap flag, editor gate) + 4 route
(report shape, no-body, viewer 403, flag-off 404) + 3 store (list_keys prefix
scoping / empty / disabled). 104 memory + boundary tests green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…6-consolidation feat(memory): deterministic consolidation health pass (A6)
Captures the strategy for the "Agent Designer" (Agent Harness Editor): a new authoring surface that composes an Agent from RBAC-governed primitives (instructions, model, KBs, tools, skills, Memory Spaces, + future), replacing the term/feature "Assistant." Locks the load-bearing decisions: own a primitive-agnostic Agent contract and federate AgentCore Registry later rather than build on it (adopt-with-boundary precedent); evolve the assistant store in place (no parallel table); a uniform bindings[] model with the model as a governed single-select; RBAC = compose the five existing per-primitive access checks (incl. ModelAccessService), not a new system; design-time filter + run-time re-resolution per invoker with block-on- missing v1; ship memory-consumption as a thin vertical slice before the full Designer. Phasing 0–5 + later AWS federation; supersedes the memory spec's "extend the Assistant" §B1 framing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…signer-spec docs(agent): Agent Designer spec — unified primitive-binding surface
…dels Phase 1 (PR-1) of the Agent Designer. Pure library, zero behavior change: legacy Assistants read unchanged and no caller passes the new fields yet. - AgentModelConfig (D3 governed single-select; field is model_settings/ alias modelConfig to dodge pydantic's reserved model_config — R3) - AgentBinding (open kind on read, KNOWN_BINDING_KINDS for request validation) - optional model_settings + bindings on Assistant (additive) - compat.effective_bindings/to_agent_view (D2): absent bindings synthesize a knowledge_base binding reffing the assistant id (KB's only stable identity, F4 deferred — R4); absent model maps to None, never fabricated (R1) - Decimal-safe serialization for modelConfig.params floats Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase 1 (PR-2). The Agent fields now round-trip through the rag-assistants store and are validated at write time by composing existing RBAC checks (D4). Legacy clients are unaffected: the SPA sends none of the new fields and the AssistantResponse surface is unchanged. - service.create_assistant/update_assistant thread bindings + model_settings; to_ddb_safe on write / from_ddb on read so modelConfig.params floats survive DynamoDB (Decimal); explicit [] replaces bindings, absent leaves them untouched - app_api/agents/services/binding_validation.py composes model access (ModelAccessService), memory resolve_permission (viewer+/editor+), the implicit-KB rejection, and inert shape-only checks for tool/skill (D4/D5) - assistants POST/PUT validate then pass through; validation raises 4xx outside the create handler's generic except so it isn't masked as 500 - tests: validation matrix (incl. inert no-RBAC guarantee), persistence round trip, legacy no-field read Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…signer-phase1 feat(agents): Agent Designer Phase 1 — contract + binding persistence (foundation)
Phase 1 (PR-3). A governed Agent read/write surface over the evolved assistant store: same shared service functions and identity-based access gates as /assistants, but returning the Agent shape (compat.to_agent_view -> AgentResponse) so callers see modelConfig + bindings. Legacy ids valid unchanged. - feature_flags.agents_enabled(): AGENTS_API_ENABLED, default OFF (memory-spaces pattern) — surface 404s while off, ships incrementally, /assistants unaffected - app_api/agents/routes.py: require_agents_enabled 404-gate; draft/create/list/ get/update/delete + 4 shares endpoints, delegating to apis.shared.assistants service and reprojecting via to_agent_view; create/update run binding_validation - AgentResponse/AgentsListResponse/AgentSharesResponse (agentId == assistantId) - main.py mounts the router - test-chat + document sub-routes deliberately excluded (would force a 2nd architecture import-boundary exception); list is owner+shared (public/pagination parity deferred to the Phase-4 Designer) - tests: 404-gate, agentId/bindings projection, CRUD permission gating, shares Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…signer-agents-router feat(agents): Agent Designer Phase 1 — /agents surface (dark)
Phase 1 (PR-4). Completes Phase 1 deployability: the /agents surface can now
be turned on per environment. No new AWS resources — the flag only gates
whether the routes 404 (the assistant store it reads is always present).
- config.ts: AgentsConfig { enabled }; CDK_AGENTS_API_ENABLED (default off,
empty-string-safe) or an `agents.enabled` cdk.json context, mirroring
memorySpaces exactly
- app-api-environment.ts: AGENTS_API_ENABLED env on app-api
- infra tests: default-off / opt-on assertion; mock-config default
- docs: agent-designer.md Phase-1 status (+ the two refinements and the
Oliver-dogfood-gated-on-Phase-3 note); CHANGELOG [Unreleased]
The live Oliver dogfood (D6) is deliberately NOT included: it needs Phase 3
harness resolution + Memory Spaces deployed to the target env before a
memory_space binding resolves at invocation. Tracked as the Phase 3 payoff.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…signer-flag-plumbing feat(agents): Agent Designer Phase 1 — AGENTS_API_ENABLED flag plumbing + docs
…se 3 PR-0) Phase 3 harness resolution runs inside inference-api, so the runtime needs the same flag the app-api surface got in #593. Default off, mirrors the app-api wiring; without it the harness ignores Agent bindings entirely (today's behavior). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…hase 3 PR-A) The Harness now re-resolves an Agent's governed modelConfig against the INVOKING user (D5) and applies it to model selection. Absent modelConfig ⇒ the model resolves exactly as today; gated on AGENTS_API_ENABLED (off in all envs still). - agent_binding_resolver.py: resolve_agent_invocation() checks the pinned model against AppRoleService.can_access_model for the invoker (R2 — same gate the harness uses elsewhere), returns a model_override or raises AgentBindingBlockedError. inference-api imports apis.shared only (boundary-safe) - routes.py /invocations: resolve after assistant load, before the KB search; on block, stream a conversational stream_error via stream_conversational_message (D5 block-with-message, no silent downgrade). Override wins at model resolution; agent params sit beneath request params, still flowing through admin bounds/locks - tests: allowed→override, denied→block (checked vs invoker), no-modelConfig→ empty plan (no RBAC call); 57 existing inference/chat tests unchanged Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…se 3 PR-B) Shared, sync helper that resolves a memory_space binding's alwaysLoad specs into injectable text fragments — the read side of Workstream B. - resolve_always_load(): MEMORY.md → index; latest:<type>/<prefix> → most-recent matching manifest entry (defines that scheme, which had no resolver); bare slug → entry. Missing entries skipped (never fails a turn). Byte-budgeted with a truncation marker pointing at memory_read (MEMORY_INJECTION_MAX_BYTES, ~24KB) - render_memory_block(): delimited system-prompt block; empty for a fresh space - reads go through MemorySpaceService (re-checks viewer+ internally) — no leak - 11 unit tests against a fake service Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…(Phase 3 PR-C) The Harness now resolves an Agent's memory_space binding against the invoking user and injects the space's alwaysLoad content (read-only) into the system prompt — the first half of the Workstream B / Oliver payoff. - agent_binding_resolver: _resolve_memory() checks the invoker's grant via MemorySpaceService.resolve_permission (D4); blocks (D5) when the flag is off, the space is gone, or a readwrite binding meets a below-editor invoker (no silent read-only downgrade). Returns ResolvedMemoryBinding (v1: first binding) - routes.py: after prompt assembly, hydrate via resolve_always_load (asyncio.to_ thread; MemorySpaceService re-checks viewer+) and append render_memory_block; best-effort — a memory-read hiccup never fails the turn - tests: memory grant matrix (none/flag-off/missing/read-viewer/readwrite-viewer- block/readwrite-editor/invoker-identity); 78 inference+compat tests green Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…signer-harness-resolution feat(agents): Agent Designer Phase 3 — harness resolution (model + read-only memory)
…el agents run-app-api.sh launches app-api with `cd src/apis/app_api && python main.py`, putting that directory on sys.path[0]. The new apis/app_api/agents/ package (Agent Designer surface, #591/#592) then shadowed the top-level `agents` package, so `admin/quota/routes.py`'s `from agents.main_agent...` resolved into it and crashed startup with `ModuleNotFoundError: No module named 'agents.main_agent'`. Tests never caught it — pytest runs from backend/ where `agents` resolves correctly. Production is unaffected (the container runs `uvicorn apis.app_api.main:app` from WORKDIR /app, so sys.path[0] is /app). Rename the package apis/app_api/agents → apis/app_api/agent_designer (and its test dir) so its name can't collide with the top-level `agents` package. Pure rename: the /agents URL surface, router, and behavior are unchanged. Verified: `import agents.main_agent.quota.repository` and the full app-api module now load from src/apis/app_api; 34 agent/boundary tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ge-name-collision fix(agents): rename app_api.agents package to unbreak local app-api startup
…(Phase 3) Completes the Workstream B write side: an Agent with a memory_space binding now gets memory_list / memory_read (always) and memory_write (readwrite bindings only) at invocation — Oliver can read AND write his space. - agents/builtin_tools/memory_spaces/: closure-scoped factories capturing the binding's space id + invoker identity, MemorySpaceService via asyncio.to_thread (artifact-tools pattern). Every call re-checks the grant inside the service (viewer+ read / editor+ write), so a revoked grant becomes an error tool-result mid-session, never a leak - routes.py _build_memory_tools(): appended to the extra_tools seam only when a memory binding resolved; write tool gated on access==readwrite. extra_tools agents are never cached → tools closed over user A can't be served to user B - not gated on enabled_tools: the governing capability is the Agent's binding, not the user's tool picker (same reasoning as artifact tools) - tests: tool success/permission-error/not-found matrix + seam counts (none=0, read=2, readwrite=3); 84 inference+tool tests green Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Memory Spaces is a complete feature (CRUD + SPA panel + agent binding), so it should ship enabled for every deployer/forker — opt-out, not opt-in — matching the kbSync / scheduledRuns convention. The table + bucket are already provisioned unconditionally in PlatformStack, so this only flips the runtime MEMORY_SPACES_ENABLED env var; no new infra footprint. - config.ts: memorySpaces.enabled default true (empty/unset workflow var = on, only literal "false" disables); interface + block docs updated - platform.yml: forward CDK_MEMORY_SPACES_ENABLED (kill switch) and CDK_AGENTS_API_ENABLED (per-env enable for the still-default-off /agents surface, so dev can turn it on for dogfooding without a code change) - app-api-environment.ts: comment reflects default-on - config.test.ts: 5 tests locking default-on + kill-switch + context override Agent Designer (AGENTS_API_ENABLED) stays default OFF until the Phase-4 Designer UI ships — a headless /agents surface helps no forker. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…mory-tools feat(agents): Agent Designer Phase 3 — memory_* tools (write side)
…paces-default-on chore(memory): default Memory Spaces ON with a kill switch
Ships the Agent Designer authoring surface (Phase 4) and its Phase-2
precursor, the bindable-primitives catalog. The pickers can't exist
without the catalog, so both land together.
Backend (Phase 2 catalog):
- GET /agents/bindable?kind=model|tool|skill|knowledge_base|memory_space
returns an RBAC-filtered palette, composing the 5 existing per-primitive
access services (D4); no new RBAC invented. Uniform BindableItem shape so
every picker consumes one contract. Route declared before /{agent_id} so
the literal path isn't captured. knowledge_base → empty (welded/synthesized);
skill/memory_space → empty when their feature flag is off. Behind
AGENTS_API_ENABLED.
- Fix binding_validation._validate_model: it resolved models via
get_managed_model() — a primary-key lookup on the internal UUID — but
modelConfig.modelId is the Bedrock model_id that the runtime resolver, RBAC
(permissions.models) and invocation all key on. A valid model would have
been rejected 400 on save the moment the picker set one. Now matches by
model_id, consistent with the whole chain.
Frontend (Phase 4 UI):
- New agents/ feature dir (separate from the Assistants editor): Agent +
Binding + BindableItem TS contracts, a thin AgentApiService, and an
AgentService signal facade with the accessible$ 404-probe idiom + a
per-kind bindable cache.
- Agents list page (model + binding-count badges) and an agent-form page:
persona/emoji/tags/starters, a required single-select model picker (D3),
tool/skill multi-select chips, and a memory-space picker with access
(read/read+write — write disabled unless editor+ on the space, per D5) and
an alwaysLoad MEMORY.md toggle. KB shown read-only. Sharing reuses the
assistants share dialog (agentId == assistantId).
- Routes agents / agents/new / agents/:id/edit, plus a sidenav "Agents"
entry gated on the accessible$ probe.
Tests: backend 1552 pass (9 new catalog + 4 new route + 3 updated
model-validation); SPA build + tsc clean, ng test 7 AgentService + 11
sidenav specs pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The sidenav constructor now probes agent accessibility (void agentService.loadAgents()), but sidenav.spec.ts didn't provide a mock AgentService, so the real service fired an unstubbed HTTP GET /agents that rejected with status 0 — vitest fails the run on unhandled errors even though all assertions passed. Provide a mock AgentService (accessible$ signal + no-op loadAgents) mirroring the schedule/memory stubs, plus parity tests for the probe + showAgents gate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…igner-phase-4-ui-666b5e feat(agent-designer): Phase 4 — Agent Designer UI + bindable catalog API
The catalog lists models via ModelAccessService.filter_accessible_models, but design-time write validation used can_access_model — and the two disagree. filter_accessible_models grants access whenever the model id is in the user's AppRole permissions.models; can_access_model only honors that membership when the model record ALSO carries a non-empty allowed_app_roles. So a model granted purely via the user's AppRole (empty allowed_app_roles) was listed by the picker but rejected on save with a 403 — and the runtime resolver (membership-based) would actually have allowed it. Validate the model with the same filter_accessible_models predicate the catalog uses, so 'if the palette offers it, the write accepts it' holds by construction. Adds a regression test for the empty-allowed_app_roles grant. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The AgentCore Runtime env block set DYNAMODB_USER_FILES_TABLE_NAME but not S3_USER_FILES_BUCKET_NAME, so the Word-document tools' _user_files_bucket() fell back to the literal 'user-files' default and PutObject failed with AccessDenied (and earlier PermanentRedirect against that unrelated bucket). The runtime role's UserFilesBucketAccess already grants Get/Put/Delete/List on the real bucket; this just points the runtime at it. tsc build passes.
…er-files-bucket-env Set S3_USER_FILES_BUCKET_NAME on inference-api runtime
_user_files_bucket() previously defaulted to a literal 'user-files' bucket when S3_USER_FILES_BUCKET_NAME was unset, which surfaced a missing runtime env var as a confusing S3 PermanentRedirect/AccessDenied. It now raises _StorageNotConfiguredError, and create/modify/read short-circuit before the Code Interpreter run with a clear 'storage is not configured' message.
…storage-config Fail loudly when Word doc storage bucket is unconfigured
…nto-develop-1.9.0 Backmerge main into develop after 1.9.0
- Add excel_spreadsheet_tool.py with create/modify/list/read tools for .xlsx files - Create office/_storage.py module with shared Code Interpreter and S3 storage utilities for Word and Excel - Implement Excel toolset integration in inference_api chat routes with tool injection - Add "Excel Spreadsheets" catalog entry to DEFAULT_TOOLS in seed_bootstrap_data.py - Replace word-document-renderer with generic file-download-renderer for all generated office documents - Extend Word document tool to use shared office storage module - Update test fixtures and chat routes to support Excel tool provisioning - Generated Excel files are persisted to S3_USER_FILES_BUCKET_NAME and appear in chat Files panel
…dsheet-tools feat(office-tools): add Excel spreadsheet toolset
Add powerpoint_presentation_tool.py with create/modify/list/read tools for .pptx files, mirroring the Word/Excel toolsets and reusing the shared office/_storage.py module (Code Interpreter + user-files storage). python-pptx runs in the sandbox; generated decks persist to S3_USER_FILES_BUCKET_NAME and render inline via the shared file_download card. - Gate key create_powerpoint_presentation injects the full toolset via _build_powerpoint_presentation_tools in inference_api chat routes - Seed 'PowerPoint Presentations' into DEFAULT_TOOLS; update seed test counts (7->8) and assertions - Add pptx MIME/extension to ALLOWED_MIME_TYPES/ALLOWED_EXTENSIONS - Frontend: file-download-renderer picks an orange presentation icon for .pptx/.ppt - Fold slide-design guidance (palettes, typography, layout variety, anti-patterns) into the create docstring in lieu of porting AWS's JS/Deno skills framework
…ction create_powerpoint_presentation gains an optional template_name: when given, the deck is built on top of that .pptx (resolved from this chat's files) so it inherits the template's slide masters, layouts, theme colors, fonts, and master/layout branding. The template's example slides are stripped first (removing slide-id refs leaves masters/layouts intact), so it starts themed-but-empty. Add list_powerpoint_layouts tool (equivalent of the AWS sample's get_presentation_layouts): reports a template's layout indices, names, and placeholders so the model targets the right layout/placeholders when building on it. Provisioned by the same create_powerpoint_presentation gate key (no new catalog entry). Wired the new tool into _build_powerpoint_presentation_tools in inference_api chat routes.
The SPA distribution's CloudFront ResponseHeadersPolicy only ever opened
frame-src to 'self' and the artifacts origin, so every domained deploy
CSP-blocked the MCP App sandbox iframe (mcp-sandbox.{domain}) — the
sandbox side's frame-ancestors was locked to the SPA origin from the
start, but the SPA side was never extended. Localhost dev bypasses
CloudFront's response headers entirely, which masked the gap through
live verification.
Thread the already-computed mcpSandboxProxyOrigin from PlatformStack
into SpaDistributionConstruct and append it to frame-src. Add a
regression test that synths a domained PlatformStack and asserts both
iframe origins are present in the frontend headers policy.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…c-mcp-sandbox fix(infra): allow the mcp-sandbox origin in the SPA frame-src CSP
Generic agent file surface over the existing user-files store, per
docs/specs/session-workspace-tools.md:
- apis/shared/files/workspace.py: DynamoDB-metadata-first list (session +
user scope), bounded ranged text reads (48KB/call with offset
continuation), binary by presigned-URL reference only (never base64),
and a write path mirroring word_document_tool._store_document (READY
FileMetadata row, source="agent", quota check + increment). Missing
identity raises — no default-user fallback.
- FileMetadata gains an additive display-only `source` field
(default "upload").
- agents/builtin_tools/workspace_tools.py: make_workspace_{list,read,
write}_tool closure factories; workspace_write returns the inline
download-card contract (ui_type "workspace_file").
- Wiring: _build_workspace_tools in inference chat routes behind the
single "workspace_files" catalog gate key (seeded, enabledByDefault
false) and the WORKSPACE_TOOLS_ENABLED default-on kill switch
(apis/shared/feature_flags.py).
- SPA: workspace_file ui_type routes to the existing download-card
renderer.
- 48 new backend tests; seed tests updated for the 7th catalog entry.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nto-develop-1.10.0 Backmerge main into develop (1.10.0)
…presentation-tools feat(office-tools): add PowerPoint presentation toolset
…rkspace-tools # Conflicts: # backend/scripts/seed_bootstrap_data.py # backend/src/apis/inference_api/chat/routes.py # backend/tests/test_seed_system_admin_jwt.py # frontend/ai.client/src/app/session/components/message-list/components/inline-visual/renderers/word-document-renderer.component.ts
…workspace-tools feat: session workspace tools (workspace_list/read/write)
create_artifact's content_type defaults to text/html, so a request like "create a markdown recipe artifact" produced raw Markdown stored verbatim as HTML — the iframe then showed run-together `#`/`**` source and the card badge read "HTML" instead of rendering the document. Add a server-side safety net: HTML-typed content that lacks a standalone HTML document shell (`<!doctype html>` / `<html>`) is reclassified as text/markdown before storage, so the writer wraps it into a proper render document and the DynamoDB row (badge + render-Lambda mapping) stays truthful. Real HTML documents, Markdown, and other MIME types pass through untouched. Applied in both create_artifact_record and update_artifact_record (the update path covers the inherited-type case where there is no argument for the model to get right). Also steer the model up front: the create_artifact docstring now says to author prose (reports, docs, recipes, mostly-text) as Markdown and to honor an explicit "markdown" request, reducing how often the backstop fires. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-markdown-coercion fix: render markdown artifacts authored under the default HTML type
Sonnet 5 sometimes persists a reasoningContent block with empty reasoningText.text and no redactedContent (a signature-only thinking block). The signature must stay in the message because Bedrock requires it on follow-up calls, but the block has nothing to display. The live stream parser already guards on reasoningText, but the history- rehydration path bypasses it and reaches displayBlocks, which pushed a Thinking display block for any truthy reasoningContent object. The reasoning-content component then renders its "Thinking" header unconditionally, so an empty collapsible appeared on reload. Guard the render decision with hasRenderableReasoning() so a reasoningContent block is only painted when it has reasoning text or redacted content -- mirroring the component's own visibility logic and the live parser's guard. Display-only: the block is left untouched in the persisted message to preserve the signature/prompt-cache contract. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…mpty-thinking-blocks-9f8bda fix: don't render empty "Thinking" blocks from signature-only reasoning
Feature release adding two new agent capabilities to chat: a PowerPoint (.pptx) presentation toolset and a generic File Workspace toolset, plus two rendering fixes. No new AWS resources and no CDK deploy required. - feat: PowerPoint presentation toolset (create/modify/list/read + layouts) behind the "PowerPoint Presentations" catalog toggle, off by default (#713) - feat: File Workspace toolset (workspace_list/read/write) behind the "File Workspace" catalog toggle + WORKSPACE_TOOLS_ENABLED kill switch (#716) - fix: render Markdown artifacts authored under the default HTML type (#720) - fix: don't paint empty "Thinking" blocks from signature-only reasoning (#721) Bump VERSION 1.10.0 -> 1.11.0 and sync manifests + lockfiles. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| import re | ||
| import uuid | ||
| from datetime import datetime, timezone | ||
| from typing import Any, Dict, List, Optional |
| import re | ||
| import uuid | ||
| from datetime import datetime, timezone | ||
| from typing import Any, Dict, List, Optional |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release 1.11.0
Feature release adding two new agent capabilities to chat plus two rendering fixes. No new AWS resources, no dependency changes, no CDK deploy required — ships via
backend.yml+frontend-deploy.yml.🚀 Added
create/modify/list/read_powerpoint_presentation+list_powerpoint_layouts, built with python-pptx in the sandboxed Code Interpreter; delivered to the chat Files panel. Single "PowerPoint Presentations" catalog toggle (gate keycreate_powerpoint_presentation), off by default (feat(office-tools): add PowerPoint presentation toolset #713)workspace_list/read/writegeneric file surface over the user-files store (read uploaded text files on demand; save Markdown/CSV/JSON deliverables). Single "File Workspace" catalog toggle (gate keyworkspace_files), off by default, gated per env by theWORKSPACE_TOOLS_ENABLEDkill switch (default ON) (feat: session workspace tools (workspace_list/read/write) #716)🐛 Fixed
text/htmltype now render formatted instead of raw#/**source (fix: render markdown artifacts authored under the default HTML type #720)Deployment notes
backend.yml+frontend-deploy.yml. Noplatform.yml/CDK deploy.enabledByDefault: false) and grant them via RBAC before users can enable them.WORKSPACE_TOOLS_ENABLEDdefaults ON; set tofalseon inference-api to disable the workspace tools for an environment.Full detail in CHANGELOG.md and RELEASE_NOTES.md.
After squash-merge into
main: backmergemain→develop(merge commit, not squash).🤖 Generated with Claude Code