feat: add configurable screenshot resolution limit

This commit is contained in:
chenmingxuan committed 2026-09-29 17:12:22 +08:00
1 parent 59f458205d
commit ab066733b8
13 files changed
+134 -4

No files matched your search

@@ -8,6 +8,8 @@ interface Capabilities {
recording_enabled: boolean;
outputter_enabled: boolean;
step_summarizer_enabled: boolean;
screenshot_limit_enabled: boolean;
screenshot_max_long_edge: number;
}
@Component({
@@ -24,6 +26,8 @@ interface Capabilities {
<span>最终报告生成<small>根据执行记录生成任务结果报告。</small></span></label>
<label><input type="checkbox" role="switch" [(ngModel)]="config.step_summarizer_enabled" [disabled]="busy() || loading() || !loaded()" />
<span>步骤摘要压缩<small>Flash 模式下在后台生成摘要,减少长任务的上下文占用。</small></span></label>
<label><input type="checkbox" role="switch" [(ngModel)]="config.screenshot_limit_enabled" [disabled]="busy() || loading() || !loaded()" />
<span>限制截图分辨率<small>开启时长边最多 {{ config.screenshot_max_long_edge }} 像素;关闭后使用设备原始分辨率。JSON 配置可覆盖开关和上限。</small></span></label>
<button type="button" (click)="save()" [disabled]="busy() || loading() || !loaded()">{{ busy() ? '正在保存…' : '保存功能设置' }}</button>
@if (message()) { <p role="status">{{ message() }}</p> }
@if (error()) { <p role="alert" class="error">{{ error() }}</p> }
@@ -39,7 +43,7 @@ interface Capabilities {
export class CapabilitySettingsComponent implements OnInit {
changed = output<Capabilities>();
private http = inject(HttpClient);
config: Capabilities = { video_enabled: false, recording_enabled: false, outputter_enabled: true, step_summarizer_enabled: true };
config: Capabilities = { video_enabled: false, recording_enabled: false, outputter_enabled: true, step_summarizer_enabled: true, screenshot_limit_enabled: true, screenshot_max_long_edge: 2048 };
busy = signal(false); loading = signal(true); loaded = signal(false); message = signal(''); error = signal('');
ngOnInit(): void {
this.http.get<Capabilities>('/api/system/capability-settings').pipe(finalize(() => this.loading.set(false))).subscribe({
@@ -110,17 +110,19 @@ describe('持久化模型与功能设置', () => {
});
it('录屏与视频分析独立保存,重新打开后保留各自状态', () => {
const capabilities = { video_enabled: true, recording_enabled: false, outputter_enabled: true, step_summarizer_enabled: false };
const capabilities = { video_enabled: true, recording_enabled: false, outputter_enabled: true, step_summarizer_enabled: false, screenshot_limit_enabled: true, screenshot_max_long_edge: 2048 };
const fixture = TestBed.createComponent(CapabilitySettingsComponent);
fixture.detectChanges();
http.expectOne('/api/system/capability-settings').flush(capabilities);
fixture.componentInstance.config.video_enabled = false;
fixture.componentInstance.config.recording_enabled = true;
fixture.componentInstance.config.screenshot_limit_enabled = false;
fixture.componentInstance.save();
const request = http.expectOne('/api/system/capability-settings');
expect(request.request.body.video_enabled).toBeFalse();
expect(request.request.body.recording_enabled).toBeTrue();
const saved = { ...capabilities, video_enabled: false, recording_enabled: true };
expect(request.request.body.screenshot_limit_enabled).toBeFalse();
const saved = { ...capabilities, video_enabled: false, recording_enabled: true, screenshot_limit_enabled: false };
request.flush(saved);
fixture.destroy();
const reopened = TestBed.createComponent(CapabilitySettingsComponent);
@@ -128,5 +130,6 @@ describe('持久化模型与功能设置', () => {
http.expectOne('/api/system/capability-settings').flush(saved);
expect(reopened.componentInstance.config.video_enabled).toBeFalse();
expect(reopened.componentInstance.config.recording_enabled).toBeTrue();
expect(reopened.componentInstance.config.screenshot_limit_enabled).toBeFalse();
});
});