sneakoscope 8.1.2 → 8.2.0
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/README.md +96 -58
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/bin/fast-inline.js +5 -51
- package/dist/cli/command-manifest-lite.js +2 -1
- package/dist/cli/command-registry.js +2 -1
- package/dist/cli/global-mode-router.js +1 -1
- package/dist/cli/install-helpers-codex-lb-config.js +112 -914
- package/dist/cli/install-helpers-codex-lb-shared.js +3 -44
- package/dist/cli/install-helpers-install-support.js +4 -20
- package/dist/cli/install-helpers.js +36 -2716
- package/dist/cli/router.js +9 -9
- package/dist/commands/bridge-command-output.js +111 -0
- package/dist/commands/bridge.js +320 -0
- package/dist/commands/codex-app.js +39 -123
- package/dist/commands/doctor-helpers.js +380 -0
- package/dist/commands/doctor-profile.js +3 -0
- package/dist/commands/doctor.js +114 -873
- package/dist/commands/mad-sks.js +0 -4
- package/dist/config/skills-manifest.json +1 -1
- package/dist/core/agents/agent-effort-policy.js +11 -21
- package/dist/core/agents/agent-recursion-guard.js +26 -0
- package/dist/core/agents/agent-runner-codex-exec.js +7 -9
- package/dist/core/architecture-hardening/contracts/contracts.js +225 -161
- package/dist/core/architecture-hardening/state/state-service.js +49 -13
- package/dist/core/auto-review.js +15 -9
- package/dist/core/codex/codex-config-guard.js +8 -0
- package/dist/core/codex-adapter.js +8 -10
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +7 -29
- package/dist/core/codex-app/codex-app-launcher.js +10 -12
- package/dist/core/codex-app/codex-app-restart.js +10 -12
- package/dist/core/codex-app/menubar/constants.js +2 -5
- package/dist/core/codex-app/menubar/global-install.js +3 -2
- package/dist/core/codex-app/menubar/installer/result.js +23 -0
- package/dist/core/codex-app/menubar/installer/runtime.js +28 -0
- package/dist/core/codex-app/menubar/installer.js +5 -96
- package/dist/core/codex-app/menubar/migration.js +1 -42
- package/dist/core/codex-app/openrouter-provider.js +0 -78
- package/dist/core/codex-app.js +97 -360
- package/dist/core/codex-control/codex-app-server-runtime-env.js +8 -28
- package/dist/core/codex-control/codex-current-image-path-real-probe.js +2 -3
- package/dist/core/codex-control/codex-current-web-search-probe.js +2 -3
- package/dist/core/codex-control/codex-sdk-adapter.js +5 -48
- package/dist/core/codex-control/codex-task-runner.js +16 -60
- package/dist/core/codex-control/desktop-bridge-launch-guard.js +227 -0
- package/dist/core/codex-exec-output-schema.js +11 -13
- package/dist/core/codex-lb/bridge-contracts.js +2 -0
- package/dist/core/codex-lb/bridge-runtime-validation/capability.js +104 -0
- package/dist/core/codex-lb/bridge-runtime-validation/catalog.js +52 -0
- package/dist/core/codex-lb/bridge-runtime-validation/shared.js +109 -0
- package/dist/core/codex-lb/bridge-runtime-validation/status.js +250 -0
- package/dist/core/codex-lb/bridge-runtime-validation.js +106 -0
- package/dist/core/codex-lb/capability-runner.js +505 -201
- package/dist/core/codex-lb/codex-lb-env.js +179 -12
- package/dist/core/codex-lb/combined-catalog/builder.js +86 -0
- package/dist/core/codex-lb/combined-catalog/contracts.js +5 -0
- package/dist/core/codex-lb/combined-catalog/normalize.js +170 -0
- package/dist/core/codex-lb/combined-catalog/persistence.js +207 -0
- package/dist/core/codex-lb/combined-catalog/shared.js +12 -0
- package/dist/core/codex-lb/combined-catalog/storage.js +171 -0
- package/dist/core/codex-lb/combined-catalog.js +12 -0
- package/dist/core/codex-lb/desktop-bridge/client.js +4 -1
- package/dist/core/codex-lb/desktop-bridge/header-policy.js +48 -63
- package/dist/core/codex-lb/desktop-bridge/http-forward.js +115 -83
- package/dist/core/codex-lb/desktop-bridge/launchd.js +20 -13
- package/dist/core/codex-lb/desktop-bridge/location-rewrite.js +4 -1
- package/dist/core/codex-lb/desktop-bridge/security.js +381 -267
- package/dist/core/codex-lb/desktop-bridge/server.js +148 -19
- package/dist/core/codex-lb/desktop-bridge/state.js +56 -70
- package/dist/core/codex-lb/desktop-bridge/types.js +6 -1
- package/dist/core/codex-lb/desktop-bridge/websocket-forward.js +281 -106
- package/dist/core/codex-lb/desktop-bridge-migration/historical-config.js +245 -0
- package/dist/core/codex-lb/desktop-bridge-migration/historical-toml.js +56 -0
- package/dist/core/codex-lb/desktop-bridge-migration/metadata.js +73 -0
- package/dist/core/codex-lb/desktop-bridge-migration/receipt.js +52 -0
- package/dist/core/codex-lb/desktop-bridge-migration/retired-runtime-cleanup.js +106 -0
- package/dist/core/codex-lb/desktop-bridge-migration/types.js +1 -0
- package/dist/core/codex-lb/desktop-bridge-migration.js +238 -0
- package/dist/core/codex-lb/desktop-controller-v3/catalog.js +257 -0
- package/dist/core/codex-lb/desktop-controller-v3/diagnostics.js +62 -0
- package/dist/core/codex-lb/desktop-controller-v3/lifecycle-commands.js +203 -0
- package/dist/core/codex-lb/desktop-controller-v3/live-probes.js +293 -0
- package/dist/core/codex-lb/desktop-controller-v3/preflight-probes.js +144 -0
- package/dist/core/codex-lb/desktop-controller-v3/provider-commands.js +182 -0
- package/dist/core/codex-lb/desktop-controller-v3/shared.js +279 -0
- package/dist/core/codex-lb/desktop-controller-v3/status.js +269 -0
- package/dist/core/codex-lb/desktop-controller-v3/types.js +1 -0
- package/dist/core/codex-lb/desktop-controller-v3/verification.js +89 -0
- package/dist/core/codex-lb/desktop-controller-v3.js +67 -0
- package/dist/core/codex-lb/desktop-controller.js +2 -1730
- package/dist/core/codex-lb/desktop-service.js +462 -627
- package/dist/core/codex-lb/migration-receipt.js +560 -118
- package/dist/core/codex-lb/probes/auxiliary-surfaces-probe.js +37 -53
- package/dist/core/codex-lb/probes/bridge-probe.js +125 -64
- package/dist/core/codex-lb/probes/catalog-probe.js +36 -136
- package/dist/core/codex-lb/probes/computer-use-probe.js +63 -39
- package/dist/core/codex-lb/probes/image-generation-probe.js +98 -41
- package/dist/core/codex-lb/probes/probe-evidence.js +32 -33
- package/dist/core/codex-lb/probes/voice-realtime-probe.js +69 -43
- package/dist/core/codex-lb/provider-credentials/configuration.js +127 -0
- package/dist/core/codex-lb/provider-credentials/locks.js +11 -0
- package/dist/core/codex-lb/provider-credentials/private-snapshot.js +28 -0
- package/dist/core/codex-lb/provider-credentials/removal.js +33 -0
- package/dist/core/codex-lb/provider-credentials/resolution.js +59 -0
- package/dist/core/codex-lb/provider-credentials/runtime.js +55 -0
- package/dist/core/codex-lb/provider-credentials/types.js +1 -0
- package/dist/core/codex-lb/provider-credentials/validation-store.js +137 -0
- package/dist/core/codex-lb/provider-credentials.js +5 -0
- package/dist/core/codex-lb/provider-registry.js +323 -0
- package/dist/core/codex-lb/provider-route-policy.js +118 -0
- package/dist/core/codex-lb/request-route-resolver.js +172 -0
- package/dist/core/codex-lb/route-index.js +148 -0
- package/dist/core/codex-lb/trusted-deep-evidence.js +158 -286
- package/dist/core/commands/basic-cli.js +1 -1
- package/dist/core/commands/check-command.js +3 -10
- package/dist/core/commands/gate-result-contract.js +10 -14
- package/dist/core/commands/intent-normalization/normalizer.js +1 -1
- package/dist/core/commands/mad-sks-command.js +2 -6
- package/dist/core/commands/release-command.js +11 -1
- package/dist/core/commands/telegram-command.js +46 -6
- package/dist/core/doctor/doctor-readiness-matrix.js +9 -7
- package/dist/core/doctor/skill-legacy-surface.js +5 -5
- package/dist/core/evidence/v2/evidence-key.js +30 -3
- package/dist/core/feature-fixtures.js +8 -1
- package/dist/core/feature-registry.js +3 -2
- package/dist/core/hooks-runtime/stop-finalization.js +11 -1
- package/dist/core/hooks-runtime/subagent-context.js +15 -1
- package/dist/core/hooks-runtime/subagent-skill-availability-contract.js +1 -1
- package/dist/core/hooks-runtime/tool-output-quarantine.js +1 -1
- package/dist/core/hooks-runtime.js +73 -87
- package/dist/core/image-ux-review/imagegen-adapter.js +108 -94
- package/dist/core/image-ux-review/real-callout-extractor.js +144 -14
- package/dist/core/imagegen/desktop-bridge-imagegen-target.js +77 -0
- package/dist/core/imagegen/imagegen-capability.js +43 -151
- package/dist/core/init/skills/filesystem.js +89 -0
- package/dist/core/init/skills/inventory.js +97 -0
- package/dist/core/init/skills/manifest.js +151 -0
- package/dist/core/init/skills.js +5 -325
- package/dist/core/init.js +0 -63
- package/dist/core/install/installed-package-smoke.js +1 -1
- package/dist/core/managed-assets/managed-assets-manifest.js +0 -1
- package/dist/core/policy/latest-version-guidance.js +15 -2
- package/dist/core/preflight/parallel-preflight-engine.js +27 -51
- package/dist/core/provider/provider-badge.js +9 -4
- package/dist/core/provider/provider-context.js +57 -107
- package/dist/core/providers/openrouter/openrouter-account.js +3 -1
- package/dist/core/providers/openrouter/openrouter-secret-store.js +91 -22
- package/dist/core/release/desktop-bridge-release-evidence.js +457 -0
- package/dist/core/release/gate-manifest.js +0 -1
- package/dist/core/release/main-push-guard.js +13 -0
- package/dist/core/release/main-push-receipt.js +11 -0
- package/dist/core/release/physical-release-gates.js +664 -61
- package/dist/core/release/publish-preflight.js +3 -3
- package/dist/core/release/release-gate-batch-runner.js +19 -6
- package/dist/core/release/release-gate-dag.js +33 -6
- package/dist/core/release/release-gate-node.js +1 -3
- package/dist/core/release/release-gate-output-contract.js +55 -0
- package/dist/core/release/release-pack-contract.js +1 -1
- package/dist/core/release/release-pack-receipt.js +209 -8
- package/dist/core/release/release-real-contract.js +1 -1
- package/dist/core/release/stage-publish.js +106 -28
- package/dist/core/retention/temp-lease.js +204 -0
- package/dist/core/retention.js +18 -195
- package/dist/core/routes.js +1 -2
- package/dist/core/safety/intent-contract/intent-contract.js +3 -3
- package/dist/core/subagents/naruto-host-credentials.js +6 -1
- package/dist/core/subagents/official-subagent-config.js +27 -9
- package/dist/core/subagents/official-subagent-runner.js +14 -31
- package/dist/core/subagents/wave-lifecycle.js +36 -8
- package/dist/core/subagents/wave-parent-guidance.js +2 -1
- package/dist/core/telegram/doctor.js +2 -2
- package/dist/core/telegram/liveness.js +10 -4
- package/dist/core/triwiki/context-graph/compiler/index.js +18 -18
- package/dist/core/update/update-migration-state/fast-mode-config.js +172 -0
- package/dist/core/update/update-migration-state/session-state-split.js +247 -0
- package/dist/core/update/update-migration-state/simple-stages.js +46 -0
- package/dist/core/update/update-migration-state.js +4 -481
- package/dist/core/version.js +1 -1
- package/dist/native/sks-menubar/Sources/OperationCoordinator.swift +28 -4
- package/dist/native/sks-menubar/Sources/OperationModels.swift +112 -2
- package/dist/native/sks-menubar/Sources/ProviderRouteExplanation.swift +21 -0
- package/dist/native/sks-menubar/Sources/ProvidersBridgeCatalog.swift +140 -0
- package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +107 -470
- package/dist/native/sks-menubar/Sources/ProvidersReliability.swift +27 -197
- package/dist/native/sks-menubar/Sources/ProvidersRoutingTruth.swift +335 -269
- package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +233 -437
- package/dist/native/sks-menubar/Sources/RemoteCodingViewController.swift +16 -7
- package/dist/native/sks-menubar/Sources/SecureProcessEnvelope.swift +39 -9
- package/dist/native/sks-menubar/Sources/TelegramSupport.swift +56 -0
- package/dist/scripts/canonical-test-runner.js +7 -1
- package/dist/scripts/check-runtime-schemas.js +7 -2
- package/dist/scripts/codex-sdk-real-smoke-check.js +3 -1
- package/dist/scripts/desktop-bridge-capabilities-check.js +123 -0
- package/dist/scripts/{codex-lb-desktop-bridge-latency-check.js → desktop-bridge-latency-check.js} +61 -16
- package/dist/scripts/desktop-bridge-real-evidence-check.js +64 -0
- package/dist/scripts/{codex-lb-desktop-bridge-check.js → desktop-bridge-transport-check.js} +92 -155
- package/dist/scripts/desktop-bridge-transport-client.js +116 -0
- package/dist/scripts/desktop-bridge-unification-check.js +276 -0
- package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +12 -8
- package/dist/scripts/gate-policy-audit-check.js +52 -2
- package/dist/scripts/provider-badge-context-check.js +55 -12
- package/dist/scripts/publish-preflight.js +1 -2
- package/dist/scripts/release-affected-selector-check.js +1 -2
- package/dist/scripts/release-aggressive-resource-governor-check.js +1 -1
- package/dist/scripts/release-cache-glob-hashing-check.js +1 -0
- package/dist/scripts/release-cache-version-neutral-fixture-check.js +1 -0
- package/dist/scripts/release-full-parallelism-blackbox.js +1 -1
- package/dist/scripts/release-gate-batch-runner-check.js +9 -0
- package/dist/scripts/release-gate-dag-runner-check.js +6 -0
- package/dist/scripts/release-gate-dag-runner.js +4 -2
- package/dist/scripts/release-metadata-check.js +16 -3
- package/dist/scripts/release-pack-receipt.js +29 -6
- package/dist/scripts/release-physical-gates-check.js +39 -0
- package/dist/scripts/release-real-check.js +7 -5
- package/package.json +6 -8
- package/release-gates.v2.json +156 -157
- package/runtime-required-scripts.json +11 -11
- package/schemas/codex/desktop-bridge-status-v3.schema.json +286 -0
- package/schemas/codex/desktop-capabilities-v3.schema.json +198 -0
- package/schemas/release/release-gate-node.schema.json +2 -3
- package/dist/cli/codex-lb-setup-warning-output.js +0 -17
- package/dist/cli/install-helpers-codex-lb-chain.js +0 -529
- package/dist/commands/codex-lb.js +0 -1232
- package/dist/core/architecture-hardening/migration/migration.js +0 -111
- package/dist/core/codex-app/auxiliary-oauth-policy.js +0 -36
- package/dist/core/codex-app/catalog-compat/catalog-service.js +0 -104
- package/dist/core/codex-app/child-policy/child-policy.js +0 -35
- package/dist/core/codex-app/desktop-routing-snapshot.js +0 -233
- package/dist/core/codex-app/glm-model-profile.js +0 -1
- package/dist/core/codex-app/glm-profile-installer.js +0 -191
- package/dist/core/codex-app/glm-profile-schema.js +0 -42
- package/dist/core/codex-app/multi-provider-router.js +0 -391
- package/dist/core/codex-app/openrouter-activate.js +0 -405
- package/dist/core/codex-app/openrouter-model-catalog.js +0 -217
- package/dist/core/codex-app/provider-child-policy.js +0 -64
- package/dist/core/codex-app/provider-mode.js +0 -91
- package/dist/core/codex-app/provider-session-policy.js +0 -85
- package/dist/core/codex-app/session-policy/session-pinning.js +0 -68
- package/dist/core/codex-control/codex-lb-launch-recovery.js +0 -319
- package/dist/core/codex-lb/codex-lb-setup.js +0 -293
- package/dist/core/codex-lb/codex-lb-tool-catalog.js +0 -456
- package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +0 -290
- package/dist/core/codex-lb/desktop-center-credentials.js +0 -1083
- package/dist/core/codex-lb/desktop-mode.js +0 -32
- package/dist/core/codex-lb/desktop-real-evidence.js +0 -168
- package/dist/core/codex-lb/legacy-migration.js +0 -576
- package/dist/core/codex-lb/native-openai-transport/transport.js +0 -68
- package/dist/core/codex-lb/provider-routing/provider-router.js +0 -58
- package/dist/core/codex-lb/routing-truth.js +0 -327
- package/dist/core/imagegen/codex-lb-imagegen-target.js +0 -92
- package/dist/native/sks-menubar/Sources/ProvidersConnectTest.swift +0 -118
- package/dist/native/sks-menubar/Sources/ProvidersFastMode.swift +0 -17
- package/dist/native/sks-menubar/Sources/ProvidersMultiProvider.swift +0 -331
- package/dist/native/sks-menubar/Sources/ProvidersRoleModels.swift +0 -260
- package/dist/scripts/codex-lb-catalog-passthrough-check.js +0 -120
- package/dist/scripts/codex-lb-desktop-auth-invariant-check.js +0 -169
- package/dist/scripts/codex-lb-desktop-capabilities-check.js +0 -287
- package/dist/scripts/codex-lb-desktop-real-evidence-check.js +0 -123
- package/dist/scripts/codex-lb-fast-mode-truth-check.js +0 -114
- package/dist/scripts/codex-lb-fast-ui-preservation-check.js +0 -152
- package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +0 -231
|
@@ -13,7 +13,7 @@ import { localizedFinalizationReason } from './language-preference.js';
|
|
|
13
13
|
import { classifyToolError } from './evaluation.js';
|
|
14
14
|
import { dollarCommand, managedSkillNamesForPrompt, stripVisibleDecisionAnswerBlocks } from './routes.js';
|
|
15
15
|
import { coreEngineeringDirectiveReferenceText } from './lean-engineering-policy.js';
|
|
16
|
-
import {
|
|
16
|
+
import { agentWorkerHookContext, agentWorkerHookRecursionDecision } from './agents/agent-recursion-guard.js';
|
|
17
17
|
import { evaluateLoopContinuation } from './loops/loop-continuation-enforcer.js';
|
|
18
18
|
import { diagnosticPromptAllowedDuringNoQuestions } from './routes/diagnostic-allowlist.js';
|
|
19
19
|
import { maybeReconcileProjectSkillsPreflight } from './hooks-runtime/skill-reconcile-preflight.js';
|
|
@@ -45,7 +45,7 @@ import { loadHookPayload, normalizeHookResult, visibleHookMessage } from './hook
|
|
|
45
45
|
import { codexGitActionMetadataSignal, codexGitActionMetadataText, compactAnswerContext, conversationId, explicitConversationId, extractCommand, extractLastMessage, extractUserPrompt, hookTurnId, looksLikeCodexGitAction, looksLikeCodexGitActionStopCompletion, looksLikeCodexUiSettingsEvent, looksLikeMadSksConfirmationPrompt, observedParentModel, toolFailed } from './hooks-runtime/payload-signals.js';
|
|
46
46
|
import { interruptedToolOutputRecoveryBlockReason, missingToolOutputCallId, missingToolOutputCallIdFromPayload, quarantineMissingToolOutput, readToolOutputQuarantine } from './hooks-runtime/tool-output-quarantine.js';
|
|
47
47
|
import { activeAuthoritativeSksSkillRefresh, activeGoalOverlayContext, attachAuthoritativeSksSkillContext, attachOfficialSubagentSpawnCompatibilityContext, authoritativeSksSkillAdmission, hookActiveSkillContextRefresh, isBlockingClarificationAwaiting, looksLikeExplicitActiveWorkflowReplacementPrompt, looksLikeClarificationCancel, routeBypassesActiveContext, routeIsGitOnly, selectedSksSkillNamesForActiveState, shouldPrepareFreshRouteOnActivePrompt, standaloneParentManagedSkillNames } from './hooks-runtime/hook-context.js';
|
|
48
|
-
import { sealedSubagentRoutingContext, subagentRouteContext } from './hooks-runtime/subagent-context.js';
|
|
48
|
+
import { officialSubagentSkillGuardBinding, sealedSubagentRoutingContext, subagentRouteContext } from './hooks-runtime/subagent-context.js';
|
|
49
49
|
export { loadHookPayload, normalizeHookResult };
|
|
50
50
|
export { refreshOfficialSubagentCompletionArtifacts };
|
|
51
51
|
export { honestModeGapLines, honestModeLoopbackBudgetExhausted } from './hooks-runtime/stop-finalization.js';
|
|
@@ -141,29 +141,36 @@ export async function evaluateHookPayload(name, payload = {}, opts = {}) {
|
|
|
141
141
|
async function hookSubagentStart(root, state, payload = {}, sessionKey = null) {
|
|
142
142
|
const artifactDir = officialSubagentArtifactDir(root, state, sessionKey);
|
|
143
143
|
const sessionArtifactDir = officialSubagentArtifactDir(root, {}, sessionKey);
|
|
144
|
+
const skillGuardBinding = officialSubagentSkillGuardBinding(state);
|
|
145
|
+
const bindingIncomplete = Boolean(skillGuardBinding && (!String(skillGuardBinding.missionId || '').trim()
|
|
146
|
+
|| !String(skillGuardBinding.workflowRunId || '').trim()));
|
|
144
147
|
const artifactDirBlockers = [];
|
|
145
|
-
const artifactDirSafe =
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
148
|
+
const artifactDirSafe = skillGuardBinding
|
|
149
|
+
? await ensureOfficialSubagentArtifactDirConfined(root, artifactDir)
|
|
150
|
+
.then(() => true)
|
|
151
|
+
.catch(() => false)
|
|
152
|
+
: true;
|
|
153
|
+
if (skillGuardBinding && !artifactDirSafe) {
|
|
149
154
|
artifactDirBlockers.push('subagent_skill_availability_artifact_dir_unsafe');
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
155
|
+
}
|
|
156
|
+
if (skillGuardBinding) {
|
|
157
|
+
await clearSubagentSkillAvailabilityGuards(root, payload, artifactDir, skillGuardBinding).catch(() => null);
|
|
158
|
+
}
|
|
154
159
|
const config = await readOfficialSubagentConfig(root);
|
|
155
160
|
const budget = resolveSubagentThreadBudget({ configuredMaxThreads: config.maxThreads });
|
|
156
161
|
const active = subagentRouteContext(state);
|
|
157
|
-
const routingContext =
|
|
158
|
-
|
|
162
|
+
const routingContext = skillGuardBinding && artifactDirSafe
|
|
163
|
+
? await sealedSubagentRoutingContext(artifactDir, payload)
|
|
164
|
+
: '';
|
|
165
|
+
const resourceGuard = skillGuardBinding ? [
|
|
159
166
|
`SKS Naruto policy: max_threads frame budget is ${budget.maxThreads} (cap, not a spawn target).`,
|
|
160
167
|
'GPT-5.6 four profiles are routing lanes, not an agent-count cap.',
|
|
161
168
|
'Use max_depth=1. Naruto children must not spawn children.',
|
|
162
169
|
'Do not duplicate an already assigned slice.',
|
|
163
170
|
'Parallel writes require disjoint paths; serialize overlapping paths.',
|
|
164
171
|
'Finish only your assigned slice, return a concise result, then stop so the Naruto parent can close this thread.'
|
|
165
|
-
].join(' ');
|
|
166
|
-
const skillNames = selectedSksSkillNamesForActiveState(state);
|
|
172
|
+
].join(' ') : '';
|
|
173
|
+
const skillNames = skillGuardBinding ? selectedSksSkillNamesForActiveState(state) : [];
|
|
167
174
|
const resolution = skillNames.length
|
|
168
175
|
? await resolveManagedSkillSourcesForAdmission({
|
|
169
176
|
root,
|
|
@@ -172,33 +179,12 @@ async function hookSubagentStart(root, state, payload = {}, sessionKey = null) {
|
|
|
172
179
|
}).catch(() => null)
|
|
173
180
|
: null;
|
|
174
181
|
const skillBlockers = [
|
|
182
|
+
...(bindingIncomplete ? ['subagent_skill_availability_guard_invalid'] : []),
|
|
175
183
|
...artifactDirBlockers,
|
|
176
184
|
...(skillNames.length ? authoritativeSksSkillResolutionBlockers(resolution) : [])
|
|
177
185
|
];
|
|
178
|
-
|
|
179
|
-
await persistSubagentSkillAvailabilityBlocker({
|
|
180
|
-
root,
|
|
181
|
-
artifactDir,
|
|
182
|
-
sessionArtifactDir,
|
|
183
|
-
state,
|
|
184
|
-
payload,
|
|
185
|
-
blockers: skillBlockers
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
catch (error) {
|
|
189
|
-
const blocker = error instanceof Error
|
|
190
|
-
&& error.message === 'subagent_skill_availability_blocker_artifact_write_failed'
|
|
191
|
-
? 'subagent_skill_availability_blocker_artifact_write_failed'
|
|
192
|
-
: 'subagent_skill_availability_guard_persistence_failed';
|
|
193
|
-
skillBlockers.push(blocker);
|
|
194
|
-
}
|
|
195
|
-
if (artifactDirSafe) {
|
|
186
|
+
if (skillGuardBinding) {
|
|
196
187
|
try {
|
|
197
|
-
await recordAndRefreshSubagentEvidence(root, state, payload, 'SubagentStart', sessionKey);
|
|
198
|
-
}
|
|
199
|
-
catch {
|
|
200
|
-
const lifecycleBlocker = await recordOfficialSubagentLifecycleCaptureFailure(artifactDir, state, payload, 'SubagentStart').catch(() => 'official_subagent_lifecycle_capture_failure_unpersisted');
|
|
201
|
-
skillBlockers.push(lifecycleBlocker);
|
|
202
188
|
await persistSubagentSkillAvailabilityBlocker({
|
|
203
189
|
root,
|
|
204
190
|
artifactDir,
|
|
@@ -206,10 +192,36 @@ async function hookSubagentStart(root, state, payload = {}, sessionKey = null) {
|
|
|
206
192
|
state,
|
|
207
193
|
payload,
|
|
208
194
|
blockers: skillBlockers
|
|
209
|
-
}).catch(() => {
|
|
210
|
-
skillBlockers.push('subagent_skill_availability_guard_persistence_failed');
|
|
211
195
|
});
|
|
212
196
|
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
const blocker = error instanceof Error
|
|
199
|
+
&& error.message === 'subagent_skill_availability_blocker_artifact_write_failed'
|
|
200
|
+
? 'subagent_skill_availability_blocker_artifact_write_failed'
|
|
201
|
+
: 'subagent_skill_availability_guard_persistence_failed';
|
|
202
|
+
skillBlockers.push(blocker);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (skillGuardBinding && artifactDirSafe) {
|
|
206
|
+
try {
|
|
207
|
+
await recordAndRefreshSubagentEvidence(root, state, payload, 'SubagentStart', sessionKey);
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
const lifecycleBlocker = await recordOfficialSubagentLifecycleCaptureFailure(artifactDir, state, payload, 'SubagentStart').catch(() => 'official_subagent_lifecycle_capture_failure_unpersisted');
|
|
211
|
+
skillBlockers.push(lifecycleBlocker);
|
|
212
|
+
if (skillGuardBinding) {
|
|
213
|
+
await persistSubagentSkillAvailabilityBlocker({
|
|
214
|
+
root,
|
|
215
|
+
artifactDir,
|
|
216
|
+
sessionArtifactDir,
|
|
217
|
+
state,
|
|
218
|
+
payload,
|
|
219
|
+
blockers: skillBlockers
|
|
220
|
+
}).catch(() => {
|
|
221
|
+
skillBlockers.push('subagent_skill_availability_guard_persistence_failed');
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
213
225
|
}
|
|
214
226
|
const skillContext = skillBlockers.length
|
|
215
227
|
? renderSubagentSkillAvailabilityHandoff(skillBlockers)
|
|
@@ -559,28 +571,28 @@ async function consumeActiveOfficialWorkflowQueue(root, missionId, workflowRunId
|
|
|
559
571
|
}
|
|
560
572
|
async function hookPreTool(root, state, payload, noQuestion, sessionKey = null) {
|
|
561
573
|
const artifactDir = officialSubagentArtifactDir(root, state, sessionKey);
|
|
562
|
-
const activeBinding = {
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
574
|
+
const activeBinding = officialSubagentSkillGuardBinding(state, { allowClosedOfficialChild: true });
|
|
575
|
+
let skillAvailabilityBlock = null;
|
|
576
|
+
if (activeBinding) {
|
|
577
|
+
const evaluateSkillAvailabilityBlock = () => subagentSkillAvailabilityPreToolBlockReason(root, payload, artifactDir, activeBinding).catch((error) => {
|
|
578
|
+
const code = error instanceof Error && error.message === 'subagent_skill_availability_guard_invalid'
|
|
579
|
+
? 'subagent_skill_availability_guard_invalid'
|
|
580
|
+
: 'subagent_skill_availability_guard_check_failed';
|
|
581
|
+
return `SKS blocked this child tool call because managed skill availability failed (${code}). Return the blocker to the root parent without using tools.`;
|
|
582
|
+
});
|
|
583
|
+
skillAvailabilityBlock = await evaluateSkillAvailabilityBlock();
|
|
584
|
+
if (isSubagentSkillAvailabilityAdmissionMissingReason(skillAvailabilityBlock)) {
|
|
585
|
+
const recovered = await recoverResumedOfficialSubagentSkillAvailabilityAdmission({
|
|
586
|
+
root,
|
|
587
|
+
payload,
|
|
588
|
+
artifactDir,
|
|
589
|
+
sessionArtifactDir: officialSubagentArtifactDir(root, {}, sessionKey),
|
|
590
|
+
activeBinding,
|
|
591
|
+
skillNames: selectedSksSkillNamesForActiveState(state)
|
|
592
|
+
}).catch(() => false);
|
|
593
|
+
if (recovered)
|
|
594
|
+
skillAvailabilityBlock = await evaluateSkillAvailabilityBlock();
|
|
595
|
+
}
|
|
584
596
|
}
|
|
585
597
|
if (skillAvailabilityBlock) {
|
|
586
598
|
return { decision: 'block', permissionDecision: 'deny', reason: skillAvailabilityBlock };
|
|
@@ -653,32 +665,6 @@ async function parentWaveGuidanceContext(root, state = {}, sessionKey = null) {
|
|
|
653
665
|
return '';
|
|
654
666
|
return renderWaveParentGuidance(guidance);
|
|
655
667
|
}
|
|
656
|
-
function agentWorkerHookRecursionDecision(state = {}, payload = {}, command = '') {
|
|
657
|
-
if (!agentWorkerHookContext(state, payload))
|
|
658
|
-
return null;
|
|
659
|
-
const guard = scanAgentTextForRecursion(command);
|
|
660
|
-
if (guard.ok)
|
|
661
|
-
return null;
|
|
662
|
-
return {
|
|
663
|
-
decision: 'block',
|
|
664
|
-
permissionDecision: 'deny',
|
|
665
|
-
reason: `Agent command recursion guard blocked nested SKS route command in Codex PreToolUse hook: ${guard.violations.join(', ')}`
|
|
666
|
-
};
|
|
667
|
-
}
|
|
668
|
-
function agentWorkerHookContext(state = {}, payload = {}) {
|
|
669
|
-
const env = {
|
|
670
|
-
...(payload.env || {}),
|
|
671
|
-
...(payload.tool_input?.env || {}),
|
|
672
|
-
...(payload.toolInput?.env || {}),
|
|
673
|
-
...(payload.input?.env || {}),
|
|
674
|
-
...(payload.tool?.input?.env || {})
|
|
675
|
-
};
|
|
676
|
-
void state;
|
|
677
|
-
return Boolean(String(env.SKS_AGENT_WORKER || '') === '1'
|
|
678
|
-
|| String(env.SKS_DISABLE_ROUTE_RECURSION || '') === '1'
|
|
679
|
-
|| payload.agent_worker === true
|
|
680
|
-
|| payload.agentWorker === true);
|
|
681
|
-
}
|
|
682
668
|
async function hookPostTool(root, state, payload, noQuestion, sessionKey = null) {
|
|
683
669
|
state = { ...state, _session_key: state?._session_key || sessionKey };
|
|
684
670
|
await Promise.all([
|
|
@@ -3,8 +3,8 @@ import fsp from 'node:fs/promises';
|
|
|
3
3
|
import { ensureDir, exists, nowIso, projectRoot, readJson, writeJsonAtomic } from '../fsx.js';
|
|
4
4
|
import { sha256File, imageDimensions } from '../wiki-image/image-hash.js';
|
|
5
5
|
import { detectImagegenCapability } from '../imagegen/imagegen-capability.js';
|
|
6
|
-
import {
|
|
7
|
-
import { CODEX_LB_PROVIDER_IMAGEGEN_EVIDENCE_CLASS, CODEX_LB_PROVIDER_OUTPUT_SOURCE, NON_CODEX_API_FALLBACK_EVIDENCE_CLASS } from '../imagegen/imagegen-evidence.js';
|
|
6
|
+
import { DESKTOP_BRIDGE_IMAGEGEN_RECOVERY_GUIDANCE, resolveDesktopBridgeImagegenTarget } from '../imagegen/desktop-bridge-imagegen-target.js';
|
|
7
|
+
import { CODEX_LB_PROVIDER_IMAGEGEN_EVIDENCE_CLASS, CODEX_LB_PROVIDER_OUTPUT_SOURCE, MOCK_FIXTURE_EVIDENCE_CLASS, NON_CODEX_API_FALLBACK_EVIDENCE_CLASS } from '../imagegen/imagegen-evidence.js';
|
|
8
8
|
import { validateGptImage2Request } from '../imagegen/gpt-image-2-request-validator.js';
|
|
9
9
|
import { parseResponsesSsePayload } from '../responses-stream.js';
|
|
10
10
|
import { withResponsesRetry } from '../responses-retry-policy.js';
|
|
@@ -14,6 +14,7 @@ import { registerImageArtifact } from '../image/image-artifact-registry.js';
|
|
|
14
14
|
const DEFAULT_OPENAI_IMAGE_EDITS_ENDPOINT = 'https://api.openai.com/v1/images/edits';
|
|
15
15
|
export const DEFAULT_IMAGEGEN_FETCH_TIMEOUT_MS = 180000;
|
|
16
16
|
const responseDeadlines = new WeakMap();
|
|
17
|
+
const runtimeDesktopBridgeTargets = new WeakSet();
|
|
17
18
|
export function buildCalloutPrompt(sourceScreenId, context = {}) {
|
|
18
19
|
return [
|
|
19
20
|
'Review this UI screenshot as a senior Toss UI/UX product designer.',
|
|
@@ -298,12 +299,11 @@ export function createFakeImagegenAdapter(opts = {}) {
|
|
|
298
299
|
}
|
|
299
300
|
export function createOpenAIImagesApiAdapter(opts = {}) {
|
|
300
301
|
const apiKey = opts.apiKey || process.env.OPENAI_API_KEY || null;
|
|
301
|
-
const
|
|
302
|
-
const codexLb = allowCodexLbApiFallback && opts.codexLb?.available === true ? opts.codexLb : null;
|
|
302
|
+
const desktopBridgeTarget = trustedDesktopBridgeTarget(opts.desktopBridgeTarget);
|
|
303
303
|
return {
|
|
304
304
|
surface: 'openai_images_api',
|
|
305
305
|
model: 'gpt-image-2',
|
|
306
|
-
available: Boolean(apiKey ||
|
|
306
|
+
available: Boolean(apiKey || desktopBridgeTarget?.selected || desktopBridgeTarget?.model),
|
|
307
307
|
async generateCalloutReview(input) {
|
|
308
308
|
const started = Date.now();
|
|
309
309
|
await ensureDir(input.output_dir);
|
|
@@ -311,15 +311,19 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
|
|
|
311
311
|
const responseArtifact = path.join(input.output_dir, 'image-ux-gpt-image-2-response.json');
|
|
312
312
|
const sourcePath = path.resolve(input.source_image_path);
|
|
313
313
|
const sourceSha = await sha256File(sourcePath);
|
|
314
|
-
const auth = await resolveImagesApiAuth({ ...opts, apiKey,
|
|
315
|
-
const useResponsesImageTool = auth.auth_source === '
|
|
314
|
+
const auth = await resolveImagesApiAuth({ ...opts, apiKey, desktopBridgeTarget });
|
|
315
|
+
const useResponsesImageTool = auth.auth_source === 'DESKTOP_BRIDGE_LOOPBACK' && Boolean(auth.responses_endpoint);
|
|
316
316
|
const effectiveEndpoint = useResponsesImageTool ? auth.responses_endpoint : auth.endpoint;
|
|
317
317
|
const responsesModel = String(auth.responses_model || '');
|
|
318
|
-
const
|
|
319
|
-
const responsesEvidenceClass =
|
|
320
|
-
?
|
|
318
|
+
const desktopBridgeSelected = useResponsesImageTool && auth.desktop_bridge_selected === true;
|
|
319
|
+
const responsesEvidenceClass = desktopBridgeSelected
|
|
320
|
+
? auth.live_evidence_allowed === true
|
|
321
|
+
? CODEX_LB_PROVIDER_IMAGEGEN_EVIDENCE_CLASS
|
|
322
|
+
: MOCK_FIXTURE_EVIDENCE_CLASS
|
|
321
323
|
: NON_CODEX_API_FALLBACK_EVIDENCE_CLASS;
|
|
322
|
-
const responsesOutputSource =
|
|
324
|
+
const responsesOutputSource = desktopBridgeSelected && auth.live_evidence_allowed === true
|
|
325
|
+
? CODEX_LB_PROVIDER_OUTPUT_SOURCE
|
|
326
|
+
: null;
|
|
323
327
|
const validation = await validateGptImage2Request({
|
|
324
328
|
provider: 'openai_images_api',
|
|
325
329
|
endpoint: String(effectiveEndpoint || ''),
|
|
@@ -333,7 +337,7 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
|
|
|
333
337
|
await writeJsonAtomic(requestArtifact, {
|
|
334
338
|
schema: 'sks.image-ux-gpt-image-2-request.v1',
|
|
335
339
|
created_at: nowIso(),
|
|
336
|
-
provider: useResponsesImageTool ? '
|
|
340
|
+
provider: useResponsesImageTool ? 'desktop_bridge_responses_image_generation' : 'openai_images_api',
|
|
337
341
|
endpoint: effectiveEndpoint,
|
|
338
342
|
auth_source: auth.auth_source,
|
|
339
343
|
auth_transport: auth.auth_transport,
|
|
@@ -363,7 +367,7 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
|
|
|
363
367
|
});
|
|
364
368
|
return { ok: false, status: 'blocked', generated_image_path: null, output_id: null, blocker: 'gpt_image_2_request_validation_failed', provider: 'openai_images_api', request_artifact: requestArtifact, response_artifact: responseArtifact, latency_ms: Date.now() - started };
|
|
365
369
|
}
|
|
366
|
-
if (auth.blocker || !auth.apiKey) {
|
|
370
|
+
if (auth.blocker || (!useResponsesImageTool && !auth.apiKey)) {
|
|
367
371
|
const blocked = {
|
|
368
372
|
schema: 'sks.image-ux-gpt-image-2-response.v1',
|
|
369
373
|
created_at: nowIso(),
|
|
@@ -373,8 +377,8 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
|
|
|
373
377
|
ok: false,
|
|
374
378
|
status: 'blocked',
|
|
375
379
|
blocker: auth.blocker,
|
|
376
|
-
setup_guidance: auth.auth_source === '
|
|
377
|
-
?
|
|
380
|
+
setup_guidance: auth.auth_source === 'DESKTOP_BRIDGE_LOOPBACK'
|
|
381
|
+
? auth.setup_guidance || DESKTOP_BRIDGE_IMAGEGEN_RECOVERY_GUIDANCE
|
|
378
382
|
: 'Set OPENAI_API_KEY only for an explicit non-Codex Images API fallback, or attach a real Codex App $imagegen output image for full SKS verification.',
|
|
379
383
|
local_only: true
|
|
380
384
|
};
|
|
@@ -386,16 +390,16 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
|
|
|
386
390
|
await writeJsonAtomic(responseArtifact, {
|
|
387
391
|
schema: 'sks.image-ux-gpt-image-2-response.v1',
|
|
388
392
|
created_at: nowIso(),
|
|
389
|
-
provider: '
|
|
393
|
+
provider: 'desktop_bridge_responses_image_generation',
|
|
390
394
|
evidence_class: 'non_codex_api_fallback',
|
|
391
395
|
model: 'gpt-image-2',
|
|
392
396
|
ok: false,
|
|
393
397
|
status: 'blocked',
|
|
394
398
|
blocker,
|
|
395
|
-
setup_guidance:
|
|
399
|
+
setup_guidance: DESKTOP_BRIDGE_IMAGEGEN_RECOVERY_GUIDANCE,
|
|
396
400
|
local_only: true
|
|
397
401
|
});
|
|
398
|
-
return { ok: false, status: 'blocked', generated_image_path: null, output_id: null, blocker, provider: '
|
|
402
|
+
return { ok: false, status: 'blocked', generated_image_path: null, output_id: null, blocker, provider: 'desktop_bridge_responses_image_generation', request_artifact: requestArtifact, response_artifact: responseArtifact, latency_ms: Date.now() - started };
|
|
399
403
|
}
|
|
400
404
|
try {
|
|
401
405
|
if (useResponsesImageTool) {
|
|
@@ -404,9 +408,7 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
|
|
|
404
408
|
const response = await fetchWithTimeout(effectiveEndpoint, {
|
|
405
409
|
method: 'POST',
|
|
406
410
|
headers: {
|
|
407
|
-
|
|
408
|
-
? { 'X-Codex-LB-API-Key': auth.apiKey }
|
|
409
|
-
: { authorization: `Bearer ${auth.apiKey}` }),
|
|
411
|
+
'x-sks-model': responsesModel,
|
|
410
412
|
'content-type': 'application/json'
|
|
411
413
|
},
|
|
412
414
|
body: JSON.stringify({
|
|
@@ -427,40 +429,41 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
|
|
|
427
429
|
}, imagegenRetryOptions(opts));
|
|
428
430
|
const { response, payload } = attemptResult;
|
|
429
431
|
if (!response.ok) {
|
|
430
|
-
await writeJsonAtomic(responseArtifact, redactedImagegenResponse(payload, false, Date.now() - started, '
|
|
431
|
-
return { ok: false, status: 'blocked', generated_image_path: null, output_id: null, blocker: imagegenErrorKind(payload), provider: '
|
|
432
|
+
await writeJsonAtomic(responseArtifact, redactedImagegenResponse(payload, false, Date.now() - started, 'desktop_bridge_responses_image_generation', { attempts, retry_log }));
|
|
433
|
+
return { ok: false, status: 'blocked', generated_image_path: null, output_id: null, blocker: imagegenErrorKind(payload), provider: 'desktop_bridge_responses_image_generation', request_artifact: requestArtifact, response_artifact: responseArtifact, latency_ms: Date.now() - started };
|
|
432
434
|
}
|
|
433
435
|
if (payload?.error) {
|
|
434
|
-
await writeJsonAtomic(responseArtifact, redactedImagegenResponse(payload, false, Date.now() - started, '
|
|
435
|
-
return { ok: false, status: 'blocked', generated_image_path: null, output_id: null, blocker: imagegenErrorKind(payload), provider: '
|
|
436
|
+
await writeJsonAtomic(responseArtifact, redactedImagegenResponse(payload, false, Date.now() - started, 'desktop_bridge_responses_image_generation'));
|
|
437
|
+
return { ok: false, status: 'blocked', generated_image_path: null, output_id: null, blocker: imagegenErrorKind(payload), provider: 'desktop_bridge_responses_image_generation', request_artifact: requestArtifact, response_artifact: responseArtifact, latency_ms: Date.now() - started };
|
|
436
438
|
}
|
|
437
439
|
const generated = findResponsesImageGenerationOutput(payload);
|
|
438
440
|
if (!generated?.b64) {
|
|
439
|
-
await writeJsonAtomic(responseArtifact, redactedImagegenResponse({ ...payload, blocker: 'missing_b64_image_output' }, false, Date.now() - started, '
|
|
440
|
-
return { ok: false, status: 'blocked', generated_image_path: null, output_id: generated?.id || null, blocker: 'missing_b64_image_output', provider: '
|
|
441
|
+
await writeJsonAtomic(responseArtifact, redactedImagegenResponse({ ...payload, blocker: 'missing_b64_image_output' }, false, Date.now() - started, 'desktop_bridge_responses_image_generation'));
|
|
442
|
+
return { ok: false, status: 'blocked', generated_image_path: null, output_id: generated?.id || null, blocker: 'missing_b64_image_output', provider: 'desktop_bridge_responses_image_generation', request_artifact: requestArtifact, response_artifact: responseArtifact, latency_ms: Date.now() - started };
|
|
441
443
|
}
|
|
442
444
|
const out = path.join(input.output_dir, `gpt-image-2-callout-${Date.now()}.png`);
|
|
443
445
|
await fsp.writeFile(out, Buffer.from(String(generated.b64), 'base64'));
|
|
444
446
|
const meta = await generatedImageMetadata(process.cwd(), out, {
|
|
445
447
|
source_screen_id: input.source_screen_id,
|
|
446
|
-
provider_surface: '
|
|
448
|
+
provider_surface: 'desktop_bridge_responses_image_generation',
|
|
447
449
|
output_id: generated.id || payload?.id || null,
|
|
448
450
|
evidence_class: responsesEvidenceClass,
|
|
449
451
|
output_source: responsesOutputSource,
|
|
450
|
-
real_generated: true
|
|
452
|
+
real_generated: auth.live_evidence_allowed === true,
|
|
453
|
+
mock: auth.live_evidence_allowed !== true
|
|
451
454
|
});
|
|
452
|
-
const imageContract = await writeGeneratedImagePathContract(input, out, '
|
|
455
|
+
const imageContract = await writeGeneratedImagePathContract(input, out, 'desktop_bridge_responses_image_generation').catch(() => null);
|
|
453
456
|
await writeJsonAtomic(responseArtifact, {
|
|
454
457
|
schema: 'sks.image-ux-gpt-image-2-response.v1',
|
|
455
458
|
created_at: nowIso(),
|
|
456
|
-
provider: '
|
|
459
|
+
provider: 'desktop_bridge_responses_image_generation',
|
|
457
460
|
evidence_class: responsesEvidenceClass,
|
|
458
461
|
model: 'gpt-image-2',
|
|
459
462
|
responses_model: responsesModel,
|
|
460
463
|
responses_model_source: auth.responses_model_source || null,
|
|
461
464
|
auth_source: auth.auth_source,
|
|
462
|
-
|
|
463
|
-
|
|
465
|
+
desktop_bridge_selected: desktopBridgeSelected,
|
|
466
|
+
desktop_bridge_route_provider: auth.route_provider_id || null,
|
|
464
467
|
ok: true,
|
|
465
468
|
status: 'generated',
|
|
466
469
|
output_image_path: out,
|
|
@@ -477,7 +480,7 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
|
|
|
477
480
|
token_cost_metadata: payload?.usage || null,
|
|
478
481
|
local_only: true
|
|
479
482
|
});
|
|
480
|
-
return { ok: true, status: 'generated', generated_image_path: out, output_id: meta.output_id, blocker: null, provider: '
|
|
483
|
+
return { ok: true, status: 'generated', generated_image_path: out, output_id: meta.output_id, blocker: null, provider: 'desktop_bridge_responses_image_generation', request_artifact: requestArtifact, response_artifact: responseArtifact, image_artifact_path_contract: imageContract?.artifact_path || null, latency_ms: Date.now() - started };
|
|
481
484
|
}
|
|
482
485
|
const sourceBytes = await fsp.readFile(sourcePath);
|
|
483
486
|
const qualityParam = imagegenQualityParam(opts);
|
|
@@ -538,7 +541,7 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
|
|
|
538
541
|
return { ok: true, status: 'generated', generated_image_path: out, output_id: meta.output_id, blocker: null, provider: 'openai_images_api', request_artifact: requestArtifact, response_artifact: responseArtifact, image_artifact_path_contract: imageContract?.artifact_path || null, latency_ms: Date.now() - started };
|
|
539
542
|
}
|
|
540
543
|
catch (err) {
|
|
541
|
-
const provider = useResponsesImageTool ? '
|
|
544
|
+
const provider = useResponsesImageTool ? 'desktop_bridge_responses_image_generation' : 'openai_images_api';
|
|
542
545
|
const payload = { error: { message: err instanceof Error ? err.message : String(err) } };
|
|
543
546
|
const response = redactedImagegenResponse(payload, false, Date.now() - started, provider);
|
|
544
547
|
await writeJsonAtomic(responseArtifact, response);
|
|
@@ -586,22 +589,20 @@ export async function generateGptImage2CalloutReview(input, opts = {}) {
|
|
|
586
589
|
return createFakeImagegenAdapter({ ...(opts.fakeAdapter || {}), mockContext: true }).generateCalloutReview(input);
|
|
587
590
|
}
|
|
588
591
|
const capability = await detectImagegenCapability(opts.capability || {}).catch(() => null);
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
592
|
+
const suppliedTarget = opts.desktopBridgeTarget
|
|
593
|
+
? trustedDesktopBridgeTarget(opts.desktopBridgeTarget)
|
|
594
|
+
: null;
|
|
595
|
+
const desktopBridgeTarget = suppliedTarget || await resolveDesktopBridgeImagegenTarget(desktopBridgeTargetInputs(opts.capability, opts.openai || opts)).catch(() => null);
|
|
596
|
+
if (!suppliedTarget && desktopBridgeTarget?.status_source === 'runtime') {
|
|
597
|
+
runtimeDesktopBridgeTargets.add(desktopBridgeTarget);
|
|
598
|
+
}
|
|
599
|
+
const managedBridgeRequested = Boolean(desktopBridgeTarget?.selected || desktopBridgeTarget?.model);
|
|
594
600
|
const allowApiFallback = (opts.allowApiFallback === true
|
|
595
601
|
|| process.env.SKS_IMAGEGEN_ALLOW_API_FALLBACK === '1'
|
|
596
|
-
||
|
|
602
|
+
|| managedBridgeRequested);
|
|
597
603
|
const openaiOptions = {
|
|
598
604
|
...(opts.openai || {}),
|
|
599
|
-
|
|
600
|
-
codexLbTarget,
|
|
601
|
-
codexLbAuthTransport: capability?.codex_lb?.cli_contract === true
|
|
602
|
-
? 'authorization-bearer'
|
|
603
|
-
: codexLbTarget?.auth_transport,
|
|
604
|
-
allowCodexLbApiFallback
|
|
605
|
+
desktopBridgeTarget
|
|
605
606
|
};
|
|
606
607
|
const codexAdapter = createCodexAppImagegenAdapter({
|
|
607
608
|
...(opts.codexApp || {}),
|
|
@@ -612,16 +613,18 @@ export async function generateGptImage2CalloutReview(input, opts = {}) {
|
|
|
612
613
|
return codexResult;
|
|
613
614
|
return createOpenAIImagesApiAdapter(openaiOptions).generateCalloutReview(input);
|
|
614
615
|
}
|
|
615
|
-
function
|
|
616
|
-
const inputs = {
|
|
616
|
+
function desktopBridgeTargetInputs(source = {}, request = {}) {
|
|
617
|
+
const inputs = {
|
|
618
|
+
explicitModel: String(request.responsesModel || source?.env?.SKS_IMAGEGEN_RESPONSES_MODEL || '').trim() || null
|
|
619
|
+
};
|
|
617
620
|
if (source?.home)
|
|
618
621
|
inputs.home = source.home;
|
|
619
|
-
if (source?.codexHome)
|
|
620
|
-
inputs.codexHome = source.codexHome;
|
|
621
622
|
if (source?.env)
|
|
622
623
|
inputs.env = source.env;
|
|
623
|
-
if (
|
|
624
|
-
inputs.
|
|
624
|
+
if (source?.desktopBridgeStatus !== undefined)
|
|
625
|
+
inputs.desktopBridgeStatus = source.desktopBridgeStatus;
|
|
626
|
+
if (source?.desktopBridgeStatusImpl)
|
|
627
|
+
inputs.desktopBridgeStatusImpl = source.desktopBridgeStatusImpl;
|
|
625
628
|
return inputs;
|
|
626
629
|
}
|
|
627
630
|
function imagegenMockContext(opts = {}) {
|
|
@@ -638,64 +641,75 @@ export function imagegenCapabilityBlocker(surface = 'Codex App $imagegen') {
|
|
|
638
641
|
blocker: 'imagegen_capability_missing',
|
|
639
642
|
surface,
|
|
640
643
|
model: 'gpt-image-2',
|
|
641
|
-
guidance: 'Run the request with gpt-image-2 through Codex App $imagegen or
|
|
644
|
+
guidance: 'Run the request with gpt-image-2 through Codex App $imagegen, or provide an explicit model routed by the verified managed Desktop Bridge. Direct provider credentials remain non-Codex fallback evidence. SKS must not fabricate or substitute a text-only review.'
|
|
642
645
|
};
|
|
643
646
|
}
|
|
644
647
|
async function resolveImagesApiAuth(opts = {}) {
|
|
645
|
-
const
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
: null);
|
|
649
|
-
if (target?.selected === true)
|
|
650
|
-
return codexLbImagesApiAuth(opts, codexLb, target);
|
|
648
|
+
const target = trustedDesktopBridgeTarget(opts.desktopBridgeTarget);
|
|
649
|
+
if (target && (target.selected || target.model))
|
|
650
|
+
return desktopBridgeImagesApiAuth(target);
|
|
651
651
|
const openAiKey = String(opts.apiKey || process.env.OPENAI_API_KEY || '').trim();
|
|
652
652
|
if (openAiKey) {
|
|
653
653
|
return {
|
|
654
654
|
apiKey: openAiKey,
|
|
655
655
|
auth_source: 'OPENAI_API_KEY',
|
|
656
656
|
auth_transport: 'authorization-bearer',
|
|
657
|
-
api_key_source: null,
|
|
658
657
|
responses_model: responsesImagegenModel(opts),
|
|
659
658
|
responses_model_source: responsesImagegenModel(opts) ? 'explicit' : null,
|
|
660
659
|
endpoint: imageEditsEndpoint(opts.baseUrl || 'https://api.openai.com/v1'),
|
|
661
660
|
responses_endpoint: responsesEndpoint(opts.baseUrl || 'https://api.openai.com/v1'),
|
|
662
|
-
blocker: null
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
apiKey: null,
|
|
668
|
-
auth_source: null,
|
|
669
|
-
auth_transport: 'authorization-bearer',
|
|
670
|
-
api_key_source: null,
|
|
671
|
-
responses_model: responsesImagegenModel(opts),
|
|
672
|
-
responses_model_source: null,
|
|
673
|
-
endpoint: imageEditsEndpoint(opts.baseUrl || 'https://api.openai.com/v1'),
|
|
674
|
-
responses_endpoint: responsesEndpoint(opts.baseUrl || 'https://api.openai.com/v1'),
|
|
675
|
-
blocker: 'openai_api_key_missing'
|
|
661
|
+
blocker: null,
|
|
662
|
+
desktop_bridge_selected: false,
|
|
663
|
+
route_provider_id: null,
|
|
664
|
+
live_evidence_allowed: false,
|
|
665
|
+
setup_guidance: null
|
|
676
666
|
};
|
|
677
667
|
}
|
|
678
|
-
return
|
|
668
|
+
return {
|
|
669
|
+
apiKey: null,
|
|
670
|
+
auth_source: null,
|
|
671
|
+
auth_transport: 'authorization-bearer',
|
|
672
|
+
responses_model: responsesImagegenModel(opts),
|
|
673
|
+
responses_model_source: null,
|
|
674
|
+
endpoint: imageEditsEndpoint(opts.baseUrl || 'https://api.openai.com/v1'),
|
|
675
|
+
responses_endpoint: responsesEndpoint(opts.baseUrl || 'https://api.openai.com/v1'),
|
|
676
|
+
blocker: 'openai_api_key_missing',
|
|
677
|
+
desktop_bridge_selected: false,
|
|
678
|
+
route_provider_id: null,
|
|
679
|
+
live_evidence_allowed: false,
|
|
680
|
+
setup_guidance: null
|
|
681
|
+
};
|
|
679
682
|
}
|
|
680
|
-
function
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
:
|
|
687
|
-
|
|
688
|
-
|
|
683
|
+
function desktopBridgeImagesApiAuth(target) {
|
|
684
|
+
return {
|
|
685
|
+
apiKey: null,
|
|
686
|
+
auth_source: 'DESKTOP_BRIDGE_LOOPBACK',
|
|
687
|
+
auth_transport: 'loopback-route',
|
|
688
|
+
responses_model: target.model || '',
|
|
689
|
+
responses_model_source: target.model_source,
|
|
690
|
+
endpoint: null,
|
|
691
|
+
responses_endpoint: target.endpoint,
|
|
692
|
+
blocker: target.blocker,
|
|
693
|
+
desktop_bridge_selected: target.selected,
|
|
694
|
+
route_provider_id: target.provider_id,
|
|
695
|
+
live_evidence_allowed: target.live_evidence_allowed,
|
|
696
|
+
setup_guidance: target.setup_guidance
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
function trustedDesktopBridgeTarget(value) {
|
|
700
|
+
if (!value || typeof value !== 'object')
|
|
701
|
+
return null;
|
|
702
|
+
const target = value;
|
|
703
|
+
const runtimeTrusted = runtimeDesktopBridgeTargets.has(target);
|
|
704
|
+
if (runtimeTrusted
|
|
705
|
+
&& target.status_source === 'runtime'
|
|
706
|
+
&& target.bridge_verified === true
|
|
707
|
+
&& target.live_evidence_allowed === true)
|
|
708
|
+
return target;
|
|
689
709
|
return {
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
api_key_source: target?.api_key_source || null,
|
|
694
|
-
responses_model: responsesImagegenModel(opts) || target?.model || '',
|
|
695
|
-
responses_model_source: responsesImagegenModel(opts) ? 'explicit' : target?.model_source || null,
|
|
696
|
-
endpoint: baseUrl ? imageEditsEndpoint(baseUrl) : null,
|
|
697
|
-
responses_endpoint: baseUrl ? responsesEndpoint(baseUrl) : null,
|
|
698
|
-
blocker
|
|
710
|
+
...target,
|
|
711
|
+
status_source: 'injected_fixture',
|
|
712
|
+
live_evidence_allowed: false
|
|
699
713
|
};
|
|
700
714
|
}
|
|
701
715
|
function imageEditsEndpoint(baseUrl = '') {
|