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
2 changes: 1 addition & 1 deletion amplifier_web/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
"""Amplifier's local web host."""
__version__ = "0.20.46"
__version__ = "0.20.47"
9 changes: 5 additions & 4 deletions amplifier_web/bundles.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,11 @@ def sanitize_export(value, path=(), secrets=None):

def offered_profiles(config, registry=None):
"""The picker and updater share one current, app-level profile authority."""
if registry is None:
path = config.registry_home / 'registry.json'
registry = json.loads(path.read_text()).get('bundles', {}) if path.exists() else {}
available = set(registry) | set(config.registrations)
# The runtime resolves aliases from scoped settings, never the persisted
# registry. Historical cache entries may still describe removed aliases;
# offering those made every component update fail during bundle loading.
# Registry metadata can decorate a configured profile, not admit one.
available = set(config.registrations)
names = (STANDALONE_PROFILES & available) | set(config.settings.get('bundle', {}).get('added', {}))
entries = BundleManager.entries(config.settings)
disabled = {row.get('name') for row in entries
Expand Down
12 changes: 11 additions & 1 deletion amplifier_web/release-notes.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
{
"schemaVersion": 1,
"releases": [
{
"version": "0.20.47",
"title": "Update configured bundles and copy useful diagnostics",
"changes": [
"Prepare only bundle profiles registered in current settings. Historical registry entries no longer appear as selectable profiles or block component updates with missing-bundle errors.",
"Copy or save an update diagnostic report in one click, including update phases, timings, installed versions and source differences from the recorded worker installation. Reports exclude credentials, private paths and conversation content.",
"Preserve the existing protection for locally changed worker dependencies. Runtime repair remains an explicit maintenance action."
],
"notices": []
},
{
"version": "0.20.46",
"title": "Prepare shared component generations and adopt updates between work",
Expand Down Expand Up @@ -28,7 +38,7 @@
"Reuse unaffected browser snapshots during scoped streaming updates while preserving private drafts, current revisions and previously delivered frames. Shared summary and navigation changes continue to invalidate conservatively.",
"Keep an exact immutable payload reference for each committed conversation view. Restart reads the last committed payload rather than a newer presentation file left by a failed save.",
"Preserve pending writer scopes and private client changes through SQL failures, failed presentation rollback and retries. Resource cleanup and reviewed deletion follow committed ownership without changing canonical transcripts or event logs.",
"Verify the scoped streaming path at a 24,000-session library scale with two independent clients. Controlled callback CPU fell by 63–69%; peak process memory was essentially unchanged. Total live-app CPU, broader global writers and full recovery cost remain separate follow-up work."
"Verify the scoped streaming path at a 24,000-session library scale with two independent clients. Controlled callback CPU fell by 63\u201369%; peak process memory was essentially unchanged. Total live-app CPU, broader global writers and full recovery cost remain separate follow-up work."
],
"notices": []
},
Expand Down
7 changes: 7 additions & 0 deletions amplifier_web/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ def schema(properties=None, required=None):
"updates.featureInstall": ("Explicitly add native-desktop to the same serving app revision, preserving installed dependencies and extras. Qualifies an isolated candidate, installs and restarts through existing idle/queue guards. Does not grant OS permission or desktop control. Inspect updates.featureResults for the durable outcome; do not replay an unknown result.", schema({"feature":{"enum":["native-desktop"]},"hostInstanceId":string(200)})),
"updates.smartToolRollback": ("Restore the previous installed Smart Tool revision when idle; preserves conversation history.", schema({"id":string(200)},["id"])),
"updates.check": ("Check published application releases and ecosystem sources for updates", schema()),
"updates.diagnostics": ("Collect a sanitized update support report, including source provenance, without credentials, chat content or private paths.", schema()),
"updates.install": ("Stage and validate available application or ecosystem updates; activate when idle. Application updates restart the host.", schema()),
"updates.rollback": ("Restore the previous ecosystem version when idle", schema()),
"settings.update": ("Change voice, workspace or update defaults. Update checks support intervalHours 1, 4, 8 or 24.", schema({"patch": {"type": "object"}})),
Expand Down Expand Up @@ -1242,6 +1243,12 @@ async def _dispatch(self, action, args=None, origin="ui", command_id=None, expec
except ValueError as exc:
raise AppError(str(exc), 404) from None
return {'accepted': True, 'revision': self.state['revision'], 'effects': [], 'result': result}
if action == 'updates.diagnostics':
if not self.update_manager:
raise AppError('Update service is unavailable.')
from .update_report import collect
result = await collect(self.update_manager)
return {'accepted': True, 'revision': self.state['revision'], 'effects': [], 'result': result}
if action == 'smartTools.readResult':
if not self.smart_tools:
raise AppError('Smart Tools service is unavailable.')
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

Loading
Loading