oysterun 1.6.0-beta.2 → 1.6.0-beta.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/oysterun.mjs +64 -17
- package/dev/client/connectivity/completed-message-neighbor-click.mjs +78 -0
- package/dev/client/connectivity/completed-message-neighbor-contract.mjs +205 -0
- package/dev/client/connectivity/completed-message-visibility.d.mts +4 -4
- package/dev/client/connectivity/completed-message-visibility.mjs +14 -11
- package/dev/client/connectivity/desktop-chat-sidebar-preference.mjs +57 -0
- package/dev/client/connectivity/host-connection-feedback.mjs +12 -1
- package/dev/client/connectivity/managed-host-browser.mjs +10 -0
- package/dev/client/connectivity/session-navigation-intent.mjs +189 -0
- package/dev/client/connectivity/session-transition-state.mjs +18 -6
- package/dev/client/connectivity/test-completed-message-neighbor-click.mjs +180 -0
- package/dev/client/web/index.html +5367 -609
- package/dev/client/web-chat/dist/assets/{ReactPrism-BwJhidYf.js → ReactPrism-C6YiTZTC.js} +1 -1
- package/dev/client/web-chat/dist/assets/{ReactPrism-BwJhidYf.js.map → ReactPrism-C6YiTZTC.js.map} +1 -1
- package/dev/client/web-chat/dist/assets/SessionsSetupApp-CKJOSPFP.js +6442 -0
- package/dev/client/web-chat/dist/assets/SessionsSetupApp-CKJOSPFP.js.map +1 -0
- package/dev/client/web-chat/dist/assets/SessionsSetupApp-Dx09Uz-6.css +1 -0
- package/dev/client/web-chat/dist/assets/index-Ae5I4LHp.js +9 -0
- package/dev/client/web-chat/dist/assets/index-Ae5I4LHp.js.map +1 -0
- package/dev/client/web-chat/dist/assets/index-CN_FoTB1.js +2 -0
- package/dev/client/web-chat/dist/assets/index-CN_FoTB1.js.map +1 -0
- package/dev/client/web-chat/dist/assets/{index--1xmQ99x.js → index-DCQFwgGf.js} +2 -2
- package/dev/client/web-chat/dist/assets/{index--1xmQ99x.js.map → index-DCQFwgGf.js.map} +1 -1
- package/dev/client/web-chat/dist/assets/matrix-entry-BV7G38kH.css +10 -0
- package/dev/client/web-chat/dist/assets/matrix-entry-abAy3aOo.js +594 -0
- package/dev/client/web-chat/dist/assets/matrix-entry-abAy3aOo.js.map +1 -0
- package/dev/client/web-chat/dist/assets/{pdf-ZjtalfgI.js → pdf-DN7oVvM6.js} +5 -5
- package/dev/client/web-chat/dist/assets/pdf-DN7oVvM6.js.map +1 -0
- package/dev/client/web-chat/dist/assets/session-notice-DlyODy1z.css +1 -0
- package/dev/client/web-chat/dist/assets/web-BlYuDlOV.js +1 -0
- package/dev/client/web-chat/dist/assets/{web-c70YaskK.js.map → web-BlYuDlOV.js.map} +1 -1
- package/dev/client/web-chat/dist/assets/web-Dabw6cJi.js +1 -0
- package/dev/client/web-chat/dist/assets/{web-BzHcZK2M.js.map → web-Dabw6cJi.js.map} +1 -1
- package/dev/client/web-chat/dist/index.html +1 -2
- package/docs/routec/dev/cloud_deplyments.md +5 -0
- package/docs/routec/dev/npm_native_dependency_install.md +6 -2
- package/docs/routec/dev/npmjs_publish.md +55 -19
- package/docs/routec/dev/p262_setup_input_file.md +117 -0
- package/docs/routec/host2_turn_started_idempotency_diagnostics.md +8 -7
- package/docs/routec/host_setup.md +39 -10
- package/docs/routec/oysterun_operation_interface_spec.md +78 -2
- package/docs/routec/provider_contract.md +35 -5
- package/host-service/README.md +36 -0
- package/host-service/adapters/claude-code-adapter.mjs +48 -5
- package/host-service/adapters/codex-app-server-adapter.mjs +320 -18
- package/host-service/adapters/debug-fixture-provider-adapter.mjs +102 -1
- package/host-service/adapters/debug-large-tool-spillover-provider-adapter.mjs +2 -0
- package/host-service/adapters/debug-p135-codex-replay-provider-adapter.mjs +2 -0
- package/host-service/adapters/debug-routec-structural-replay-provider-adapter.mjs +2 -0
- package/host-service/agent-config.mjs +16 -5
- package/host-service/agent-folder-availability.mjs +41 -0
- package/host-service/apns-complete-message-dispatcher.mjs +1 -0
- package/host-service/assets/product-skills/Oysterun/modules/oysterun-find-context/SKILL.md +24 -0
- package/host-service/assets/product-skills/Oysterun/modules/oysterun-session-chat/SKILL.md +94 -5
- package/host-service/assets/product-skills/Oysterun/modules/oysterun-sessions/SKILL.md +103 -0
- package/host-service/assets/product-skills/Oysterun/modules/oysterun-website/SKILL.md +7 -0
- package/host-service/assets/product-skills/oysterun-find-context/SKILL.md +24 -0
- package/host-service/assets/product-skills/oysterun-session-chat/SKILL.md +94 -5
- package/host-service/assets/product-skills/oysterun-sessions/SKILL.md +103 -0
- package/host-service/assets/product-skills/oysterun-website/SKILL.md +7 -0
- package/host-service/callback-durable-store.mjs +354 -47
- package/host-service/callback-foundation.mjs +21 -1
- package/host-service/callback-host-integration.mjs +345 -30
- package/host-service/claude-acp-model-discovery.mjs +23 -18
- package/host-service/cli/assert-installer-reinstall-target.mjs +9 -0
- package/host-service/cli/installer-recovery-guidance.mjs +20 -0
- package/host-service/cli/prepare-restart-restore.mjs +2 -0
- package/host-service/cli/product-cli.mjs +34 -33
- package/host-service/cli/reconcile-initial-preflight.mjs +19 -0
- package/host-service/cli/recover-installer-lifecycle.mjs +24 -0
- package/host-service/cli/run-host-lifecycle.mjs +2 -0
- package/host-service/cli/run-staged-lifecycle-recovery.mjs +161 -0
- package/host-service/codex-model-discovery.mjs +23 -18
- package/host-service/complete-cli-uninstall.mjs +176 -0
- package/host-service/complete-message-notification-predicate.mjs +8 -6
- package/host-service/complete-message-notification-title.mjs +4 -0
- package/host-service/completed-session-unread.mjs +425 -42
- package/host-service/completed-turn-navigation.mjs +444 -144
- package/host-service/completed-turn-notification-observer.mjs +116 -0
- package/host-service/completed-turn-service.mjs +445 -0
- package/host-service/config.mjs +115 -9
- package/host-service/desired-open-session-state.mjs +331 -0
- package/host-service/fixtures/p218-completed-turn-notification.json +11 -0
- package/host-service/frp-agent.mjs +9 -9
- package/host-service/grok-acp-model-discovery.mjs +31 -33
- package/host-service/host-lifecycle-recovery.mjs +37 -0
- package/host-service/host-port-resolution.mjs +98 -0
- package/host-service/host-runtime-diagnostics.mjs +18 -1
- package/host-service/initial-preflight-recovery.mjs +71 -0
- package/host-service/installer-recovery-guidance.mjs +85 -0
- package/host-service/installer-reinstall-bindings.mjs +49 -0
- package/host-service/installer-reinstall-target.mjs +49 -0
- package/host-service/legacy-continuity-observation.mjs +33 -0
- package/host-service/lifecycle-compat-cli.mjs +13 -0
- package/host-service/lifecycle-compat-preload.mjs +89 -0
- package/host-service/lifecycle-compatibility.mjs +164 -0
- package/host-service/lifecycle-continuity-assets.mjs +222 -0
- package/host-service/lifecycle-continuity-probe.mjs +97 -0
- package/host-service/lifecycle-continuity-projection.mjs +29 -0
- package/host-service/lifecycle-continuity-runner.mjs +192 -0
- package/host-service/lifecycle-continuity.mjs +493 -0
- package/host-service/lifecycle-service-render-bundle.mjs +120 -0
- package/host-service/lifecycle-user-path.mjs +34 -0
- package/host-service/link-annotations.mjs +10 -0
- package/host-service/matrix-credential-issuer.mjs +32 -1
- package/host-service/matrix-event-correlator.mjs +166 -27
- package/host-service/matrix-facade.mjs +96 -19
- package/host-service/matrix-room-binding.mjs +24 -0
- package/host-service/matrix-transcript-read-adapter.mjs +17 -3
- package/host-service/model-discovery-guardian.mjs +40 -0
- package/host-service/model-discovery-process.mjs +141 -0
- package/host-service/onboard-lifecycle-status.mjs +28 -0
- package/host-service/onboard.mjs +479 -0
- package/host-service/package.json +2 -1
- package/host-service/portable-scheduler-definitions.mjs +28 -0
- package/host-service/product-runtime-host-origin.mjs +22 -0
- package/host-service/provider-model-params.mjs +14 -17
- package/host-service/provider-model-refresh-runner.mjs +124 -169
- package/host-service/provider-model-refresh-schedule.mjs +11 -0
- package/host-service/provider-resume-contract.mjs +9 -3
- package/host-service/restart-restore-state.mjs +25 -0
- package/host-service/retained-host-state-holder.mjs +57 -0
- package/host-service/routec-matrix-sqlite-store.mjs +155 -10
- package/host-service/routec-matrix-storage-adapter.mjs +208 -25
- package/host-service/routec-matrix-storage-paths.mjs +12 -0
- package/host-service/routec-request-delay-window.mjs +55 -0
- package/host-service/scheduler-acp-provider-runner.mjs +2 -1
- package/host-service/scheduler-direct-provider-runner.mjs +71 -9
- package/host-service/scheduler-run-timeout-policy.mjs +85 -0
- package/host-service/scheduler-service.mjs +96 -9
- package/host-service/scheduler-store.mjs +9 -2
- package/host-service/server.mjs +2202 -552
- package/host-service/service-definition-migration.mjs +10 -3
- package/host-service/session-collection-service.mjs +320 -0
- package/host-service/session-history.mjs +99 -15
- package/host-service/session-list-preview-service.mjs +87 -12
- package/host-service/session-list-projection-service.mjs +182 -0
- package/host-service/session-loop-definitions.mjs +702 -75
- package/host-service/session-manager.mjs +473 -38
- package/host-service/session-switcher-projection.mjs +11 -3
- package/host-service/session-tags.mjs +451 -0
- package/host-service/session-transcript-target.mjs +103 -0
- package/host-service/setup-input-file.mjs +91 -0
- package/host-service/setup-provider-model-defaults.mjs +53 -0
- package/host-service/setup.mjs +133 -101
- package/host-service/stopped-user-host-package.mjs +60 -0
- package/host-service/test-fixtures/p236-navigation-original.mjs +500 -0
- package/host-service/update-reminder-state.mjs +7 -0
- package/host-service/voice-input-receipt-store.mjs +60 -0
- package/package.json +1 -1
- package/static/oysterun-social-preview.png +0 -0
- package/static/site/assets/oysterun-social-preview.png +0 -0
- package/static/site/blog/en/index.html +17 -0
- package/static/site/blog/generated_manifest.json +9 -9
- package/static/site/blog/index.html +18 -0
- package/static/site/blog/voice-input-model-experiment/en/index.html +17 -0
- package/static/site/blog/voice-input-model-experiment/zh/index.html +17 -0
- package/static/site/blog/zh/index.html +17 -0
- package/static/site/docs/choose-and-recover-a-provider/en/index.html +17 -0
- package/static/site/docs/choose-and-recover-a-provider/zh/index.html +17 -0
- package/static/site/docs/configure-session-files-and-settings/en/index.html +17 -0
- package/static/site/docs/configure-session-files-and-settings/zh/index.html +17 -0
- package/static/site/docs/en/index.html +17 -0
- package/static/site/docs/generated_manifest.json +60 -60
- package/static/site/docs/host-authentication-and-connection/en/index.html +17 -0
- package/static/site/docs/host-authentication-and-connection/zh/index.html +17 -0
- package/static/site/docs/index.html +18 -0
- package/static/site/docs/install-and-use-a-skill/en/index.html +17 -0
- package/static/site/docs/install-and-use-a-skill/zh/index.html +17 -0
- package/static/site/docs/read-large-tool-results/en/index.html +17 -0
- package/static/site/docs/read-large-tool-results/zh/index.html +17 -0
- package/static/site/docs/recover-from-a-host-runtime-error/en/index.html +17 -0
- package/static/site/docs/recover-from-a-host-runtime-error/zh/index.html +17 -0
- package/static/site/docs/restore-work-after-a-host-restart/en/index.html +17 -0
- package/static/site/docs/restore-work-after-a-host-restart/zh/index.html +17 -0
- package/static/site/docs/send-images-and-media/en/index.html +17 -0
- package/static/site/docs/send-images-and-media/zh/index.html +17 -0
- package/static/site/docs/set-up-and-understand-a-host/en/index.html +17 -0
- package/static/site/docs/set-up-and-understand-a-host/zh/index.html +17 -0
- package/static/site/docs/understand-agent-activity/en/index.html +19 -2
- package/static/site/docs/understand-agent-activity/en/index.md +2 -2
- package/static/site/docs/understand-agent-activity/zh/index.html +19 -2
- package/static/site/docs/understand-agent-activity/zh/index.md +2 -2
- package/static/site/docs/use-the-oysterun-cli-safely/en/index.html +17 -0
- package/static/site/docs/use-the-oysterun-cli-safely/zh/index.html +17 -0
- package/static/site/docs/zh/index.html +17 -0
- package/static/site/en/index.html +18 -1
- package/static/site/en/index.md +1 -1
- package/static/site/faq/en/index.html +17 -0
- package/static/site/faq/index.html +18 -0
- package/static/site/faq/zh/index.html +17 -0
- package/static/site/getting-started/en/index.html +23 -1
- package/static/site/getting-started/en/index.md +7 -1
- package/static/site/getting-started/index.html +18 -0
- package/static/site/getting-started/zh/index.html +23 -1
- package/static/site/getting-started/zh/index.md +7 -1
- package/static/site/index.html +18 -0
- package/static/site/install.sh +676 -127
- package/static/site/overview/en/index.html +18 -1
- package/static/site/overview/en/index.md +2 -2
- package/static/site/overview/index.html +18 -0
- package/static/site/overview/zh/index.html +18 -1
- package/static/site/overview/zh/index.md +2 -2
- package/static/site/privacy/en/index.html +17 -0
- package/static/site/privacy/index.html +18 -0
- package/static/site/privacy/zh/index.html +17 -0
- package/static/site/zh/index.html +18 -1
- package/static/site/zh/index.md +1 -1
- package/static/site_source/content/tutorials/published/understand-agent-activity/en/article.html +2 -2
- package/static/site_source/content/tutorials/published/understand-agent-activity/zh/article.html +2 -2
- package/static/site_source/downloads/install.sh +676 -127
- package/static/site_source/manifests/host_install.json +2 -10
- package/static/site_source/pages/getting-started/en.html +6 -1
- package/static/site_source/pages/getting-started/zh.html +6 -1
- package/static/site_source/pages/home/en.html +1 -1
- package/static/site_source/pages/home/zh.html +1 -1
- package/static/site_source/pages/home_main.html +3 -2
- package/static/site_source/pages/overview/en.html +1 -1
- package/static/site_source/pages/overview/zh.html +1 -1
- package/tool_scripts/install_oysterun_update.mjs +78 -13
- package/tool_scripts/oysterun_continuity_transaction.mjs +438 -0
- package/tool_scripts/oysterun_npm_package_manifest.mjs +32 -0
- package/tool_scripts/oysterun_release_service.sh +5 -0
- package/tool_scripts/oysterun_service_common.sh +59 -24
- package/tool_scripts/oysterun_setup_input.sh +97 -0
- package/tool_scripts/oysterun_update_restart_runner.mjs +19 -3
- package/tool_scripts/p233_legacy_bootstrap.mjs +254 -0
- package/tool_scripts/resolve_user_host_port.mjs +15 -0
- package/tool_scripts/restart_oysterun.sh +8 -2
- package/tool_scripts/stack_dashboard_credentials.mjs +2 -1
- package/tool_scripts/status_oysterun_launch_agents.sh +13 -1
- package/tool_scripts/sync_host_stack_config.mjs +9 -6
- package/tool_scripts/test_environment_remote_cloud_deprovision.mjs +419 -0
- package/tool_scripts/uninstall_oysterun_launch_agents.sh +3 -5
- package/dev/client/web-chat/dist/assets/index-Ce9NZBZf.js +0 -129
- package/dev/client/web-chat/dist/assets/index-Ce9NZBZf.js.map +0 -1
- package/dev/client/web-chat/dist/assets/index-DzIClZ3T.js +0 -2
- package/dev/client/web-chat/dist/assets/index-DzIClZ3T.js.map +0 -1
- package/dev/client/web-chat/dist/assets/index-NYnaSGBb.css +0 -1
- package/dev/client/web-chat/dist/assets/pdf-ZjtalfgI.js.map +0 -1
- package/dev/client/web-chat/dist/assets/web-BzHcZK2M.js +0 -1
- package/dev/client/web-chat/dist/assets/web-c70YaskK.js +0 -1
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
recordHostTelemetryCounter,
|
|
28
28
|
recordHostTelemetryFeature,
|
|
29
29
|
} from "./host-telemetry.mjs";
|
|
30
|
+
import { resolveSchedulerRunTimeout } from "./scheduler-run-timeout-policy.mjs";
|
|
30
31
|
|
|
31
32
|
const SCHEDULER_LOOP_ACTIVE_REASON =
|
|
32
33
|
"P12.2 in-session loop CLI dispatch is enabled";
|
|
@@ -59,7 +60,7 @@ function recordSchedulerRunTelemetry(status) {
|
|
|
59
60
|
recordHostTelemetryCounter("scheduler_run_count");
|
|
60
61
|
if (status === "dispatched") {
|
|
61
62
|
recordHostTelemetryCounter("scheduler_run_success_count");
|
|
62
|
-
} else if (status === "failed") {
|
|
63
|
+
} else if (status === "failed" || status === "timed_out") {
|
|
63
64
|
recordHostTelemetryCounter("scheduler_run_failed_count");
|
|
64
65
|
}
|
|
65
66
|
recordHostTelemetryFeature("scheduler");
|
|
@@ -404,6 +405,7 @@ function getHostScheduleRunOutcome(run) {
|
|
|
404
405
|
? metadata.provider_exit_code
|
|
405
406
|
: null;
|
|
406
407
|
if (run.status === "failed") return "failed";
|
|
408
|
+
if (run.status === "timed_out") return "timed_out";
|
|
407
409
|
if (run.status === "skipped") return "skipped";
|
|
408
410
|
if (exitCode === 0) return "success";
|
|
409
411
|
return run.status || null;
|
|
@@ -423,8 +425,15 @@ function buildProviderRunMetadata({
|
|
|
423
425
|
? providerRun.exit_code
|
|
424
426
|
: null;
|
|
425
427
|
const signal = normalizeOptionalString(providerRun?.signal);
|
|
428
|
+
const timedOut =
|
|
429
|
+
signal === "timeout" ||
|
|
430
|
+
providerRun?.error_summary === "scheduler_provider_run_timed_out";
|
|
426
431
|
const outcome =
|
|
427
|
-
providerRun?.ok === true && exitCode === 0
|
|
432
|
+
providerRun?.ok === true && exitCode === 0
|
|
433
|
+
? "success"
|
|
434
|
+
: timedOut
|
|
435
|
+
? "timed_out"
|
|
436
|
+
: "failed";
|
|
428
437
|
const startedAt = normalizeOptionalString(providerRun?.started_at);
|
|
429
438
|
const completedAt = normalizeOptionalString(providerRun?.completed_at);
|
|
430
439
|
return {
|
|
@@ -449,7 +458,7 @@ function buildProviderRunMetadata({
|
|
|
449
458
|
providerRun?.log_summary ||
|
|
450
459
|
fallbackLogSummary ||
|
|
451
460
|
"Host scheduler direct provider run finished",
|
|
452
|
-
...(outcome
|
|
461
|
+
...(outcome !== "success"
|
|
453
462
|
? {
|
|
454
463
|
error_summary:
|
|
455
464
|
providerRun?.error_summary ||
|
|
@@ -654,6 +663,7 @@ export class SchedulerService {
|
|
|
654
663
|
portableDefinitionStore = null,
|
|
655
664
|
clock = () => new Date(),
|
|
656
665
|
recheckMs = SCHEDULER_BUSY_RECHECK_MS,
|
|
666
|
+
sessionLoopUnavailableGraceMs = undefined,
|
|
657
667
|
sessionLoopService = null,
|
|
658
668
|
} = {}) {
|
|
659
669
|
this.store = store;
|
|
@@ -673,6 +683,9 @@ export class SchedulerService {
|
|
|
673
683
|
new SessionLoopDefinitionService({
|
|
674
684
|
clock,
|
|
675
685
|
recheckMs,
|
|
686
|
+
...(sessionLoopUnavailableGraceMs === undefined
|
|
687
|
+
? {}
|
|
688
|
+
: { unavailableGraceMs: sessionLoopUnavailableGraceMs }),
|
|
676
689
|
lifecycleStore: new SessionLoopLifecycleStore({
|
|
677
690
|
configDir: store.configDir,
|
|
678
691
|
clock,
|
|
@@ -916,6 +929,22 @@ export class SchedulerService {
|
|
|
916
929
|
});
|
|
917
930
|
}
|
|
918
931
|
|
|
932
|
+
resolveSessionLoopIncidentForGui({
|
|
933
|
+
hostSessionId,
|
|
934
|
+
agentId,
|
|
935
|
+
agentFolder,
|
|
936
|
+
scheduleId,
|
|
937
|
+
action,
|
|
938
|
+
}) {
|
|
939
|
+
return this.sessionLoopService.resolveIncidentForGui({
|
|
940
|
+
hostSessionId,
|
|
941
|
+
agentId,
|
|
942
|
+
agentFolder,
|
|
943
|
+
scheduleId,
|
|
944
|
+
action,
|
|
945
|
+
});
|
|
946
|
+
}
|
|
947
|
+
|
|
919
948
|
clearSessionLoopRuntimeState({ hostSessionId, reason = "session_stop" }) {
|
|
920
949
|
return this.sessionLoopService.clearRuntimeSession({
|
|
921
950
|
hostSessionId,
|
|
@@ -962,6 +991,8 @@ export class SchedulerService {
|
|
|
962
991
|
rule,
|
|
963
992
|
timezone = getHostSystemTimezone(),
|
|
964
993
|
enabled = true,
|
|
994
|
+
runTimeoutSeconds = undefined,
|
|
995
|
+
runTimeoutSource = null,
|
|
965
996
|
}) {
|
|
966
997
|
const normalizedRule = normalizeScheduleRule(rule, { timezone });
|
|
967
998
|
const now = nowIso(this.clock);
|
|
@@ -985,6 +1016,10 @@ export class SchedulerService {
|
|
|
985
1016
|
const scheduleHostSessionId = `portable:${normalizedTargetBinding.setup_snapshot.agent_folder}`;
|
|
986
1017
|
const normalizedPrompt = normalizeHostSchedulePrompt(prompt);
|
|
987
1018
|
const active = enabled === true;
|
|
1019
|
+
const runTimeout = resolveSchedulerRunTimeout(runTimeoutSeconds, {
|
|
1020
|
+
present: runTimeoutSeconds !== undefined,
|
|
1021
|
+
source: runTimeoutSource,
|
|
1022
|
+
});
|
|
988
1023
|
return {
|
|
989
1024
|
hostSessionId: scheduleHostSessionId,
|
|
990
1025
|
agentId: normalizedAgentId,
|
|
@@ -996,6 +1031,7 @@ export class SchedulerService {
|
|
|
996
1031
|
availabilityReason: active
|
|
997
1032
|
? HOST_SCHEDULE_ACTIVE_REASON
|
|
998
1033
|
: HOST_SCHEDULE_UI_PAUSED_REASON,
|
|
1034
|
+
runTimeout,
|
|
999
1035
|
metadata: {
|
|
1000
1036
|
source: "p12_5_host_scheduler_dashboard_ui",
|
|
1001
1037
|
schedule_rule: normalizedRule,
|
|
@@ -1026,6 +1062,7 @@ export class SchedulerService {
|
|
|
1026
1062
|
rule,
|
|
1027
1063
|
timezone = getHostSystemTimezone(),
|
|
1028
1064
|
enabled = true,
|
|
1065
|
+
runTimeoutSeconds = undefined,
|
|
1029
1066
|
}) {
|
|
1030
1067
|
this.initialize();
|
|
1031
1068
|
const normalized = this.normalizeDashboardHostScheduleInput({
|
|
@@ -1036,6 +1073,7 @@ export class SchedulerService {
|
|
|
1036
1073
|
rule,
|
|
1037
1074
|
timezone,
|
|
1038
1075
|
enabled,
|
|
1076
|
+
runTimeoutSeconds,
|
|
1039
1077
|
});
|
|
1040
1078
|
const runtimeSetupSnapshot = normalized.metadata.target_binding.setup_snapshot;
|
|
1041
1079
|
const schedule = this.portableDefinitionStore.createSchedule(
|
|
@@ -1052,6 +1090,10 @@ export class SchedulerService {
|
|
|
1052
1090
|
schedule_rule: normalized.metadata.schedule_rule,
|
|
1053
1091
|
timezone: normalized.metadata.timezone,
|
|
1054
1092
|
setup_snapshot: runtimeSetupSnapshot,
|
|
1093
|
+
run_timeout_seconds: normalized.runTimeout.seconds,
|
|
1094
|
+
run_timeout_source: normalized.runTimeout.source === "explicit"
|
|
1095
|
+
? "explicit"
|
|
1096
|
+
: "default",
|
|
1055
1097
|
metadata: normalized.metadata,
|
|
1056
1098
|
},
|
|
1057
1099
|
{ agentFolder: runtimeSetupSnapshot.agent_folder }
|
|
@@ -1092,6 +1134,15 @@ export class SchedulerService {
|
|
|
1092
1134
|
const enabled = enabledProvided
|
|
1093
1135
|
? input.enabled === true
|
|
1094
1136
|
: existing.status === "active";
|
|
1137
|
+
const runTimeout = inputHas("runTimeoutSeconds")
|
|
1138
|
+
? resolveSchedulerRunTimeout(input.runTimeoutSeconds, {
|
|
1139
|
+
present: true,
|
|
1140
|
+
source: "explicit",
|
|
1141
|
+
})
|
|
1142
|
+
: resolveSchedulerRunTimeout(existing.run_timeout_seconds, {
|
|
1143
|
+
present: true,
|
|
1144
|
+
source: existing.run_timeout_source,
|
|
1145
|
+
});
|
|
1095
1146
|
const normalized = this.normalizeDashboardHostScheduleInput({
|
|
1096
1147
|
targetBinding,
|
|
1097
1148
|
hostSessionId,
|
|
@@ -1100,6 +1151,8 @@ export class SchedulerService {
|
|
|
1100
1151
|
rule,
|
|
1101
1152
|
timezone,
|
|
1102
1153
|
enabled,
|
|
1154
|
+
runTimeoutSeconds: runTimeout.seconds,
|
|
1155
|
+
runTimeoutSource: runTimeout.source,
|
|
1103
1156
|
});
|
|
1104
1157
|
const preserveNextRunAt =
|
|
1105
1158
|
!inputHas("rule") &&
|
|
@@ -1124,6 +1177,8 @@ export class SchedulerService {
|
|
|
1124
1177
|
schedule_rule: normalized.metadata.schedule_rule,
|
|
1125
1178
|
timezone: normalized.metadata.timezone,
|
|
1126
1179
|
setup_snapshot: normalized.metadata.target_binding.setup_snapshot,
|
|
1180
|
+
run_timeout_seconds: runTimeout.seconds,
|
|
1181
|
+
run_timeout_source: runTimeout.source,
|
|
1127
1182
|
metadata: normalized.metadata,
|
|
1128
1183
|
});
|
|
1129
1184
|
return {
|
|
@@ -1293,6 +1348,7 @@ export class SchedulerService {
|
|
|
1293
1348
|
prompt,
|
|
1294
1349
|
rule,
|
|
1295
1350
|
timezone = getHostSystemTimezone(),
|
|
1351
|
+
runTimeoutSeconds = undefined,
|
|
1296
1352
|
}) {
|
|
1297
1353
|
this.initialize();
|
|
1298
1354
|
const normalized = this.normalizeDashboardHostScheduleInput({
|
|
@@ -1303,6 +1359,7 @@ export class SchedulerService {
|
|
|
1303
1359
|
rule,
|
|
1304
1360
|
timezone,
|
|
1305
1361
|
enabled: true,
|
|
1362
|
+
runTimeoutSeconds,
|
|
1306
1363
|
});
|
|
1307
1364
|
const runtimeSetupSnapshot = normalized.metadata.target_binding.setup_snapshot;
|
|
1308
1365
|
const schedule = this.portableDefinitionStore.createSchedule(
|
|
@@ -1319,6 +1376,10 @@ export class SchedulerService {
|
|
|
1319
1376
|
schedule_rule: normalized.metadata.schedule_rule,
|
|
1320
1377
|
timezone: normalized.metadata.timezone,
|
|
1321
1378
|
setup_snapshot: runtimeSetupSnapshot,
|
|
1379
|
+
run_timeout_seconds: normalized.runTimeout.seconds,
|
|
1380
|
+
run_timeout_source: normalized.runTimeout.source === "explicit"
|
|
1381
|
+
? "explicit"
|
|
1382
|
+
: "default",
|
|
1322
1383
|
metadata: {
|
|
1323
1384
|
...normalized.metadata,
|
|
1324
1385
|
source: "browser_root_portable_host_scheduler_model",
|
|
@@ -1451,7 +1512,12 @@ export class SchedulerService {
|
|
|
1451
1512
|
}
|
|
1452
1513
|
|
|
1453
1514
|
async drainSingleSessionLoopDue(loopSchedule, { now, dispatcher }) {
|
|
1454
|
-
const
|
|
1515
|
+
const current = this.sessionLoopService.refreshDueLoopForDispatch(loopSchedule);
|
|
1516
|
+
if (!current) return {
|
|
1517
|
+
status: "skipped", schedule_id: loopSchedule.definition.id,
|
|
1518
|
+
reason: "loop_occurrence_superseded",
|
|
1519
|
+
};
|
|
1520
|
+
const { runtime, definition, state } = current;
|
|
1455
1521
|
const triggeredAt = normalizeRequiredString(now, "now");
|
|
1456
1522
|
const serializedSchedule = this.sessionLoopService.serializeForFeedback({
|
|
1457
1523
|
definition,
|
|
@@ -1611,6 +1677,8 @@ export class SchedulerService {
|
|
|
1611
1677
|
claimed_target_binding: structuredClone(targetBinding),
|
|
1612
1678
|
trigger_basis: "schedule_rule_after_actual_trigger_time",
|
|
1613
1679
|
actual_triggered_at: triggeredAt,
|
|
1680
|
+
run_timeout_seconds: schedule.run_timeout_seconds,
|
|
1681
|
+
run_timeout_source: schedule.run_timeout_source,
|
|
1614
1682
|
...buildHostScheduleDispatchProvenance({
|
|
1615
1683
|
dispatchOrigin,
|
|
1616
1684
|
dispatchAuthority,
|
|
@@ -1652,6 +1720,9 @@ export class SchedulerService {
|
|
|
1652
1720
|
mailCapability
|
|
1653
1721
|
);
|
|
1654
1722
|
if (safeProviderRun?.ok !== true) {
|
|
1723
|
+
const timedOut =
|
|
1724
|
+
safeProviderRun?.signal === "timeout" ||
|
|
1725
|
+
safeProviderRun?.error_summary === "scheduler_provider_run_timed_out";
|
|
1655
1726
|
const reason =
|
|
1656
1727
|
safeProviderRun?.log_summary ||
|
|
1657
1728
|
safeProviderRun?.error_summary ||
|
|
@@ -1662,7 +1733,7 @@ export class SchedulerService {
|
|
|
1662
1733
|
const statusAfter = nextRunAt ? "active" : "stopped";
|
|
1663
1734
|
const failedRun = this.store.updateScheduleRun(run.id, {
|
|
1664
1735
|
completedAt: safeProviderRun?.completed_at || triggeredAt,
|
|
1665
|
-
status: "failed",
|
|
1736
|
+
status: timedOut ? "timed_out" : "failed",
|
|
1666
1737
|
error: reason,
|
|
1667
1738
|
metadata: {
|
|
1668
1739
|
...claimedMetadata,
|
|
@@ -1703,7 +1774,7 @@ export class SchedulerService {
|
|
|
1703
1774
|
});
|
|
1704
1775
|
}
|
|
1705
1776
|
return {
|
|
1706
|
-
status: "failed",
|
|
1777
|
+
status: timedOut ? "timed_out" : "failed",
|
|
1707
1778
|
schedule_id: schedule.id,
|
|
1708
1779
|
run_id: failedRun.id,
|
|
1709
1780
|
reason,
|
|
@@ -1863,6 +1934,8 @@ export class SchedulerService {
|
|
|
1863
1934
|
claimed_target_binding: structuredClone(targetBinding),
|
|
1864
1935
|
trigger_basis: "manual_dashboard_test_run",
|
|
1865
1936
|
actual_triggered_at: triggeredAt,
|
|
1937
|
+
run_timeout_seconds: schedule.run_timeout_seconds,
|
|
1938
|
+
run_timeout_source: schedule.run_timeout_source,
|
|
1866
1939
|
next_run_at_preserved: schedule.next_run_at,
|
|
1867
1940
|
...buildHostScheduleDispatchProvenance({
|
|
1868
1941
|
dispatchOrigin,
|
|
@@ -1906,6 +1979,9 @@ export class SchedulerService {
|
|
|
1906
1979
|
mailCapability
|
|
1907
1980
|
);
|
|
1908
1981
|
if (safeProviderRun?.ok !== true) {
|
|
1982
|
+
const timedOut =
|
|
1983
|
+
safeProviderRun?.signal === "timeout" ||
|
|
1984
|
+
safeProviderRun?.error_summary === "scheduler_provider_run_timed_out";
|
|
1909
1985
|
const reason =
|
|
1910
1986
|
safeProviderRun?.log_summary ||
|
|
1911
1987
|
safeProviderRun?.error_summary ||
|
|
@@ -1914,7 +1990,7 @@ export class SchedulerService {
|
|
|
1914
1990
|
: "scheduler_direct_provider_run_failed");
|
|
1915
1991
|
const failedRun = this.store.updateScheduleRun(run.id, {
|
|
1916
1992
|
completedAt: safeProviderRun?.completed_at || triggeredAt,
|
|
1917
|
-
status: "failed",
|
|
1993
|
+
status: timedOut ? "timed_out" : "failed",
|
|
1918
1994
|
error: reason,
|
|
1919
1995
|
metadata: {
|
|
1920
1996
|
...claimedMetadata,
|
|
@@ -1956,10 +2032,10 @@ export class SchedulerService {
|
|
|
1956
2032
|
const retainedSchedule =
|
|
1957
2033
|
this.portableDefinitionStore.getSchedule(schedule.id);
|
|
1958
2034
|
return {
|
|
1959
|
-
status: "test_run_failed",
|
|
2035
|
+
status: timedOut ? "test_run_timed_out" : "test_run_failed",
|
|
1960
2036
|
schedule_id: schedule.id,
|
|
1961
2037
|
run: {
|
|
1962
|
-
status: "failed",
|
|
2038
|
+
status: timedOut ? "timed_out" : "failed",
|
|
1963
2039
|
schedule_id: schedule.id,
|
|
1964
2040
|
run_id: failedRun.id,
|
|
1965
2041
|
reason,
|
|
@@ -2609,6 +2685,10 @@ export class SchedulerService {
|
|
|
2609
2685
|
provider_command: metadata.provider_command || null,
|
|
2610
2686
|
exit_code: exitCode,
|
|
2611
2687
|
signal: metadata.provider_signal || null,
|
|
2688
|
+
run_timeout_seconds:
|
|
2689
|
+
metadata.run_timeout_seconds || schedule.run_timeout_seconds,
|
|
2690
|
+
run_timeout_source:
|
|
2691
|
+
metadata.run_timeout_source || schedule.run_timeout_source,
|
|
2612
2692
|
log_summary: redactHostScheduleTextForApi(
|
|
2613
2693
|
metadata.log_summary,
|
|
2614
2694
|
tokens
|
|
@@ -2656,12 +2736,19 @@ export class SchedulerService {
|
|
|
2656
2736
|
targetBinding,
|
|
2657
2737
|
inputText
|
|
2658
2738
|
);
|
|
2739
|
+
const runTimeout = resolveSchedulerRunTimeout(schedule.run_timeout_seconds, {
|
|
2740
|
+
present: schedule.run_timeout_seconds !== undefined,
|
|
2741
|
+
source: schedule.run_timeout_source,
|
|
2742
|
+
});
|
|
2659
2743
|
return {
|
|
2660
2744
|
id: schedule.id,
|
|
2661
2745
|
host_session: serializeHostScheduleSessionBoundary(schedule),
|
|
2662
2746
|
agent: serializeHostScheduleAgentBoundary(schedule),
|
|
2663
2747
|
schedule_kind: schedule.schedule_kind,
|
|
2664
2748
|
status: schedule.status,
|
|
2749
|
+
run_timeout_seconds: runTimeout.seconds,
|
|
2750
|
+
run_timeout_source: runTimeout.source,
|
|
2751
|
+
run_timeout_explicit: runTimeout.explicit,
|
|
2665
2752
|
next_run_at: schedule.next_run_at,
|
|
2666
2753
|
rule: metadata.schedule_rule
|
|
2667
2754
|
? serializeScheduleRuleForSummary(metadata.schedule_rule)
|
|
@@ -79,6 +79,7 @@ function normalizeRunStatus(value) {
|
|
|
79
79
|
"dispatched",
|
|
80
80
|
"skipped",
|
|
81
81
|
"failed",
|
|
82
|
+
"timed_out",
|
|
82
83
|
"canceled",
|
|
83
84
|
].includes(status)
|
|
84
85
|
) {
|
|
@@ -240,7 +241,7 @@ export class SchedulerStore {
|
|
|
240
241
|
scheduled_for TEXT NOT NULL,
|
|
241
242
|
claimed_at TEXT,
|
|
242
243
|
completed_at TEXT,
|
|
243
|
-
status TEXT NOT NULL CHECK (status IN ('planned', 'claimed', 'dispatched', 'skipped', 'failed', 'canceled')),
|
|
244
|
+
status TEXT NOT NULL CHECK (status IN ('planned', 'claimed', 'dispatched', 'skipped', 'failed', 'timed_out', 'canceled')),
|
|
244
245
|
dispatched_message_id TEXT,
|
|
245
246
|
error TEXT,
|
|
246
247
|
metadata_json TEXT,
|
|
@@ -352,6 +353,12 @@ export class SchedulerStore {
|
|
|
352
353
|
if (hasForeignKeys(this.db, "schedule_runs")) {
|
|
353
354
|
this.rebuildScheduleRunsWithoutForeignKeys();
|
|
354
355
|
}
|
|
356
|
+
const scheduleRunsSql = this.db
|
|
357
|
+
.prepare("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'schedule_runs'")
|
|
358
|
+
.get()?.sql;
|
|
359
|
+
if (!String(scheduleRunsSql || "").includes("'timed_out'")) {
|
|
360
|
+
this.rebuildScheduleRunsWithoutForeignKeys();
|
|
361
|
+
}
|
|
355
362
|
if (hasForeignKeys(this.db, "schedule_run_logs")) {
|
|
356
363
|
this.rebuildScheduleRunLogsWithoutForeignKeys();
|
|
357
364
|
}
|
|
@@ -374,7 +381,7 @@ export class SchedulerStore {
|
|
|
374
381
|
scheduled_for TEXT NOT NULL,
|
|
375
382
|
claimed_at TEXT,
|
|
376
383
|
completed_at TEXT,
|
|
377
|
-
status TEXT NOT NULL CHECK (status IN ('planned', 'claimed', 'dispatched', 'skipped', 'failed', 'canceled')),
|
|
384
|
+
status TEXT NOT NULL CHECK (status IN ('planned', 'claimed', 'dispatched', 'skipped', 'failed', 'timed_out', 'canceled')),
|
|
378
385
|
dispatched_message_id TEXT,
|
|
379
386
|
error TEXT,
|
|
380
387
|
metadata_json TEXT,
|