codex-flow 2.1.13__tar.gz → 2.1.14__tar.gz
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.
- {codex_flow-2.1.13/codex_flow.egg-info → codex_flow-2.1.14}/PKG-INFO +3 -3
- {codex_flow-2.1.13 → codex_flow-2.1.14}/README.en.md +2 -2
- {codex_flow-2.1.13 → codex_flow-2.1.14}/README.md +2 -2
- codex_flow-2.1.14/VERSION +1 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/chatgpt-mcp/server.py +1 -1
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Controllers/OverlayWindowController.swift +63 -4
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Services/IPCServer.swift +4 -4
- codex_flow-2.1.14/benchmark/prices/gpt-6-astra-2026-09-12.json +22 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/benchmark/profiles.json +32 -2
- {codex_flow-2.1.13 → codex_flow-2.1.14/codex_flow.egg-info}/PKG-INFO +3 -3
- {codex_flow-2.1.13 → codex_flow-2.1.14}/codex_flow.egg-info/SOURCES.txt +1 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/analyze-benchmark.py +4 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/benchmark-local.py +3 -3
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/render-benchmark-report.py +18 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/run-benchmark.py +53 -14
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/update-homebrew-formula.py +3 -3
- codex_flow-2.1.13/VERSION +0 -1
- {codex_flow-2.1.13 → codex_flow-2.1.14}/LICENSE +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/MANIFEST.in +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/chatgpt-mcp/README.md +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/chatgpt-mcp/__init__.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/chatgpt-mcp/adapter.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/chatgpt-mcp/widget.html +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/README.en.md +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/README.md +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Controllers/OverlayRuntimeState.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Controllers/OverlayScreenGeometry.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Localization.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Models/TelemetryData.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Services/AccountSnapshotService.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Services/FlowPilotInstanceLock.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Services/TelemetryQueryEngine.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Services/TelemetryWatcher.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Services/UpdateService.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Views/AccountView.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Views/AnalyticsView.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Views/AutostartView.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Views/BubbleView.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Views/HistoryView.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Views/HoverRevealText.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Views/InspectorSkillsToolsView.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Views/LogoView.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Views/SleekSwitch.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Views/StrategyModeView.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Views/SummaryView.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Views/UpdateView.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/main.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Tests/OverlayScreenGeometryTests.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Tests/TelemetryPhase1ContractTests.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Tests/TelemetryQueryEngineConcurrencyTests.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Tests/TelemetryQuotaSelectionTests.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Tests/TelemetryWorkerTokenTests.swift +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/build.sh +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/benchmark/corpus.json +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/benchmark/manifest.example.json +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/benchmark/manifest.schema.json +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/benchmark/prices/gpt-5.6-2026-08-30.json +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/benchmark/schema.json +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/benchmark/tasks.json +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/codex_flow.egg-info/dependency_links.txt +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/codex_flow.egg-info/entry_points.txt +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/codex_flow.egg-info/top_level.txt +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/completions/codex-flow.bash +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/completions/codex-flow.zsh +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/glama.json +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/install-release.ps1 +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/install-release.sh +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/install.ps1 +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/install.sh +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/packaging/pypi/__init__.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/packaging/pypi/__main__.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/packaging/pypi/cli.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/packaging/pypi/mcp.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/policy/benchmark.toml +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/policy/defaults.toml +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/pyproject.toml +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/check-recommendation.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/doctor.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/generate-release-manifest.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/localization.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/manage-hooks.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/manage-instructions.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/manage-shell.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/materialize-corpus.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/menu.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/migrations/0001_update_settings.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/package-release.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/strategies/__init__.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/strategies/balanced.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/strategies/base.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/strategies/efficient.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/strategies/lifecycle_runtime.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/strategies/quality.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/strategies/speed.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/strategies/task_budget_runtime.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/strategies/task_phase_runtime.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/strategies/work_unit_runtime.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/strategy_runtime.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/telemetry.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/telemetry_core/__init__.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/telemetry_core/app_server.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/telemetry_core/collector.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/telemetry_core/common.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/telemetry_core/latency.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/telemetry_core/query.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/telemetry_core/quota_ledger.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/telemetry_core/render.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/telemetry_core/repair.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/ui.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/update_runtime_config.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/scripts/updater.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/setup.cfg +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/setup.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/smithery.yaml +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/templates/agents/worker-explorer.toml +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/templates/agents/worker-implementer.toml +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/templates/agents/worker-reviewer.toml +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/templates/flow-pilot-instructions.md +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/templates/skills/flow-pilot/SKILL.md +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/tests/test_hook_trust.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/tests/test_instructions.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/tests/test_quota_ledger.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/tests/test_shared_strategy_lifecycle.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/tests/test_task_phase_runtime.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/tests/test_telemetry_worker_correlation.py +0 -0
- {codex_flow-2.1.13 → codex_flow-2.1.14}/tests/test_updater.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codex-flow
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.14
|
|
4
4
|
Summary: Intelligent, Efficient, Adaptive Multi-Agent Strategy Orchestration for Codex
|
|
5
5
|
Home-page: https://github.com/ParsifalC/codex-flow
|
|
6
6
|
Author: Parsifal
|
|
@@ -45,7 +45,7 @@ Dynamic: requires-python
|
|
|
45
45
|
|
|
46
46
|
**智能、高效、自适应的 Codex 多 Agent 策略编排引擎**
|
|
47
47
|
|
|
48
|
-
[](VERSION)
|
|
49
49
|
[](https://github.com/ParsifalC/homebrew-tap)
|
|
50
50
|
[](https://pypi.org/project/codex-flow/)
|
|
51
51
|
[](#-快速安装)
|
|
@@ -256,7 +256,7 @@ codex-flow
|
|
|
256
256
|
|
|
257
257
|
```text
|
|
258
258
|
╭────────────────────────────────────────────────────────────────────╮
|
|
259
|
-
│ 🚀 codex-flow 控制台 (v2.1.
|
|
259
|
+
│ 🚀 codex-flow 控制台 (v2.1.14) │
|
|
260
260
|
│ FlowPilot 智能编排 · 确定性任务遥测 · 本地 Benchmark 验证 │
|
|
261
261
|
╰────────────────────────────────────────────────────────────────────╯
|
|
262
262
|
[1] 🪟 macOS 原生悬浮窗 (overlay widget)
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
**Intelligent, Efficient, Adaptive Multi-Agent Strategy Orchestration for Codex**
|
|
10
10
|
|
|
11
|
-
[](VERSION)
|
|
12
12
|
[](https://github.com/ParsifalC/homebrew-tap)
|
|
13
13
|
[](https://pypi.org/project/codex-flow/)
|
|
14
14
|
[](#-quick-start)
|
|
@@ -217,7 +217,7 @@ The latest console also integrates Overlay build/start management, effective pol
|
|
|
217
217
|
|
|
218
218
|
```text
|
|
219
219
|
╭────────────────────────────────────────────────────────────────────╮
|
|
220
|
-
│ 🚀 codex-flow Console (v2.1.
|
|
220
|
+
│ 🚀 codex-flow Console (v2.1.14) │
|
|
221
221
|
│ FlowPilot orchestration · deterministic telemetry · validation │
|
|
222
222
|
╰────────────────────────────────────────────────────────────────────╯
|
|
223
223
|
[1] 🪟 macOS native floating widget (overlay widget)
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
**智能、高效、自适应的 Codex 多 Agent 策略编排引擎**
|
|
10
10
|
|
|
11
|
-
[](VERSION)
|
|
12
12
|
[](https://github.com/ParsifalC/homebrew-tap)
|
|
13
13
|
[](https://pypi.org/project/codex-flow/)
|
|
14
14
|
[](#-快速安装)
|
|
@@ -219,7 +219,7 @@ codex-flow
|
|
|
219
219
|
|
|
220
220
|
```text
|
|
221
221
|
╭────────────────────────────────────────────────────────────────────╮
|
|
222
|
-
│ 🚀 codex-flow 控制台 (v2.1.
|
|
222
|
+
│ 🚀 codex-flow 控制台 (v2.1.14) │
|
|
223
223
|
│ FlowPilot 智能编排 · 确定性任务遥测 · 本地 Benchmark 验证 │
|
|
224
224
|
╰────────────────────────────────────────────────────────────────────╯
|
|
225
225
|
[1] 🪟 macOS 原生悬浮窗 (overlay widget)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.1.14
|
|
@@ -11,7 +11,13 @@ public enum DockEdge: String, Codable {
|
|
|
11
11
|
// MARK: - Shared Observable State
|
|
12
12
|
public class OverlayState: ObservableObject {
|
|
13
13
|
@Published public var isExpanded: Bool = false
|
|
14
|
-
@Published public var isPinned: Bool = false
|
|
14
|
+
@Published public var isPinned: Bool = false {
|
|
15
|
+
didSet {
|
|
16
|
+
if isPinned {
|
|
17
|
+
windowController?.cancelNotificationAutoCollapseTimer()
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
15
21
|
@Published public var isTaskRunning: Bool = false
|
|
16
22
|
@Published public var isDocked: Bool = false
|
|
17
23
|
@Published public var dockEdge: DockEdge = .right
|
|
@@ -55,14 +61,24 @@ public class OverlayState: ObservableObject {
|
|
|
55
61
|
}
|
|
56
62
|
}
|
|
57
63
|
|
|
58
|
-
public func expand() {
|
|
59
|
-
|
|
64
|
+
public func expand(notificationTriggered: Bool = false) {
|
|
65
|
+
if isExpanded {
|
|
66
|
+
if notificationTriggered {
|
|
67
|
+
DispatchQueue.main.async {
|
|
68
|
+
self.windowController?.scheduleNotificationAutoCollapse()
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return
|
|
72
|
+
}
|
|
60
73
|
loadMenuData()
|
|
61
74
|
DispatchQueue.main.async {
|
|
62
75
|
self.windowController?.prepareForPresentationChange()
|
|
63
76
|
self.isDocked = false
|
|
64
77
|
self.isExpanded = true
|
|
65
78
|
self.windowController?.updateWindowFrame(animated: true)
|
|
79
|
+
if notificationTriggered {
|
|
80
|
+
self.windowController?.scheduleNotificationAutoCollapse()
|
|
81
|
+
}
|
|
66
82
|
}
|
|
67
83
|
}
|
|
68
84
|
|
|
@@ -354,6 +370,7 @@ class TrackingHostingView<Content: View>: NSHostingView<Content> {
|
|
|
354
370
|
isDragging = false
|
|
355
371
|
windowController.cancelDwellTimer()
|
|
356
372
|
windowController.cancelTuckTimer()
|
|
373
|
+
windowController.cancelNotificationAutoCollapseTimer()
|
|
357
374
|
super.mouseDown(with: event)
|
|
358
375
|
}
|
|
359
376
|
|
|
@@ -529,6 +546,8 @@ public class OverlayWindowController: NSObject, NSWindowDelegate {
|
|
|
529
546
|
|
|
530
547
|
private var hoverDwellTimer: Timer?
|
|
531
548
|
private var collapseTimer: Timer?
|
|
549
|
+
private var notificationCollapseTimer: Timer?
|
|
550
|
+
private let notificationAutoCollapseDuration: TimeInterval = 5.0
|
|
532
551
|
private var tuckTimer: Timer?
|
|
533
552
|
private let edgeTuckIdleInterval: TimeInterval = 30.0
|
|
534
553
|
|
|
@@ -612,6 +631,7 @@ public class OverlayWindowController: NSObject, NSWindowDelegate {
|
|
|
612
631
|
public func prepareForPresentationChange() {
|
|
613
632
|
cancelDwellTimer()
|
|
614
633
|
cancelTuckTimer()
|
|
634
|
+
cancelNotificationAutoCollapseTimer()
|
|
615
635
|
collapseTimer?.invalidate()
|
|
616
636
|
collapseTimer = nil
|
|
617
637
|
}
|
|
@@ -719,6 +739,9 @@ public class OverlayWindowController: NSObject, NSWindowDelegate {
|
|
|
719
739
|
return true
|
|
720
740
|
}
|
|
721
741
|
reconcilePointerAfterGeometryIfNeeded()
|
|
742
|
+
if state.isExpanded && isPointerInAppWindowOrPopover() {
|
|
743
|
+
cancelNotificationAutoCollapseTimer()
|
|
744
|
+
}
|
|
722
745
|
return false
|
|
723
746
|
}
|
|
724
747
|
|
|
@@ -813,6 +836,7 @@ public class OverlayWindowController: NSObject, NSWindowDelegate {
|
|
|
813
836
|
}
|
|
814
837
|
|
|
815
838
|
public func handleMouseEntered(at point: NSPoint) {
|
|
839
|
+
cancelNotificationAutoCollapseTimer()
|
|
816
840
|
if isGeometryTransitioning {
|
|
817
841
|
needsPointerReconciliationAfterGeometry = true
|
|
818
842
|
return
|
|
@@ -833,6 +857,7 @@ public class OverlayWindowController: NSObject, NSWindowDelegate {
|
|
|
833
857
|
}
|
|
834
858
|
|
|
835
859
|
public func handleMouseMoved(at point: NSPoint) {
|
|
860
|
+
cancelNotificationAutoCollapseTimer()
|
|
836
861
|
if isGeometryTransitioning {
|
|
837
862
|
needsPointerReconciliationAfterGeometry = true
|
|
838
863
|
return
|
|
@@ -892,7 +917,41 @@ public class OverlayWindowController: NSObject, NSWindowDelegate {
|
|
|
892
917
|
}
|
|
893
918
|
}
|
|
894
919
|
|
|
895
|
-
|
|
920
|
+
public func scheduleNotificationAutoCollapse(duration: TimeInterval? = nil) {
|
|
921
|
+
cancelNotificationAutoCollapseTimer()
|
|
922
|
+
let interval = duration ?? notificationAutoCollapseDuration
|
|
923
|
+
guard state.isExpanded,
|
|
924
|
+
!state.isPinned,
|
|
925
|
+
!isInteractingOrDragging else { return }
|
|
926
|
+
|
|
927
|
+
if isPointerInAppWindowOrPopover() {
|
|
928
|
+
return
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
let timer = Timer(timeInterval: interval, repeats: false) { [weak self] _ in
|
|
932
|
+
guard let self,
|
|
933
|
+
self.state.isExpanded,
|
|
934
|
+
!self.state.isPinned,
|
|
935
|
+
!self.isInteractingOrDragging,
|
|
936
|
+
!self.isGeometryTransitioning else { return }
|
|
937
|
+
|
|
938
|
+
if self.isPointerInAppWindowOrPopover() {
|
|
939
|
+
self.cancelNotificationAutoCollapseTimer()
|
|
940
|
+
return
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
self.state.collapse()
|
|
944
|
+
}
|
|
945
|
+
RunLoop.main.add(timer, forMode: .common)
|
|
946
|
+
notificationCollapseTimer = timer
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
public func cancelNotificationAutoCollapseTimer() {
|
|
950
|
+
notificationCollapseTimer?.invalidate()
|
|
951
|
+
notificationCollapseTimer = nil
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
public func isPointerInAppWindowOrPopover() -> Bool {
|
|
896
955
|
let mouseLocation = NSEvent.mouseLocation
|
|
897
956
|
for appWindow in NSApp.windows {
|
|
898
957
|
guard appWindow.isVisible,
|
|
@@ -196,23 +196,23 @@ public class IPCService {
|
|
|
196
196
|
var run = try? JSONDecoder().decode(TaskRun.self, from: data) {
|
|
197
197
|
TelemetryQueryEngine.shared.enrichRunIfNeeded(&run)
|
|
198
198
|
state.update(run: run)
|
|
199
|
-
state.expand()
|
|
199
|
+
state.expand(notificationTriggered: true)
|
|
200
200
|
return "{\"ok\": true, \"updatedFrom\": \"last.json\"}\n"
|
|
201
201
|
}
|
|
202
|
-
state.expand()
|
|
202
|
+
state.expand(notificationTriggered: true)
|
|
203
203
|
return "{\"ok\": true, \"action\": \"expanded\"}\n"
|
|
204
204
|
} else {
|
|
205
205
|
if let fileData = try? Data(contentsOf: URL(fileURLWithPath: payload)),
|
|
206
206
|
var run = try? JSONDecoder().decode(TaskRun.self, from: fileData) {
|
|
207
207
|
TelemetryQueryEngine.shared.enrichRunIfNeeded(&run)
|
|
208
208
|
state.update(run: run)
|
|
209
|
-
state.expand()
|
|
209
|
+
state.expand(notificationTriggered: true)
|
|
210
210
|
return "{\"ok\": true, \"updatedFrom\": \"file\"}\n"
|
|
211
211
|
} else if let json = payload.data(using: .utf8),
|
|
212
212
|
var run = try? JSONDecoder().decode(TaskRun.self, from: json) {
|
|
213
213
|
TelemetryQueryEngine.shared.enrichRunIfNeeded(&run)
|
|
214
214
|
state.update(run: run)
|
|
215
|
-
state.expand()
|
|
215
|
+
state.expand(notificationTriggered: true)
|
|
216
216
|
return "{\"ok\": true, \"updatedFrom\": \"json\"}\n"
|
|
217
217
|
}
|
|
218
218
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"gpt-5.6-luna": {
|
|
3
|
+
"input": 0.2,
|
|
4
|
+
"cached_input": 0.02,
|
|
5
|
+
"output": 1.2
|
|
6
|
+
},
|
|
7
|
+
"gpt-5.6-terra": {
|
|
8
|
+
"input": 2.0,
|
|
9
|
+
"cached_input": 0.2,
|
|
10
|
+
"output": 12.0
|
|
11
|
+
},
|
|
12
|
+
"gpt-5.6-sol": {
|
|
13
|
+
"input": 4.0,
|
|
14
|
+
"cached_input": 0.4,
|
|
15
|
+
"output": 20.0
|
|
16
|
+
},
|
|
17
|
+
"gpt-6-astra": {
|
|
18
|
+
"input": 10.0,
|
|
19
|
+
"cached_input": 1.0,
|
|
20
|
+
"output": 50.0
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
]
|
|
32
32
|
},
|
|
33
33
|
"full": {
|
|
34
|
-
"description": "Three repetitions across three high direct models, fixed-high flow, and adaptive-effort flow.",
|
|
34
|
+
"description": "Three repetitions across three high direct models, fixed-high flow, and adaptive-effort flow. Includes Astra/high parent with the real efficient FlowPilot runtime.",
|
|
35
35
|
"repetitions": 3,
|
|
36
36
|
"matrix": [
|
|
37
37
|
{"id": "luna-direct", "strategy": "direct", "model": "gpt-5.6-luna", "reasoning_effort": "high"},
|
|
@@ -56,11 +56,26 @@
|
|
|
56
56
|
"model": "gpt-5.6-luna",
|
|
57
57
|
"reasoning_effort": {"routine": "high", "complex": "xhigh", "critical": "max"}
|
|
58
58
|
}
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"id": "codex-flow-runtime-astra-high",
|
|
62
|
+
"strategy": "runtime",
|
|
63
|
+
"reasoning_policy": "fixed",
|
|
64
|
+
"profile": "efficient",
|
|
65
|
+
"routing_mode": "delegate",
|
|
66
|
+
"parent": {
|
|
67
|
+
"model": "gpt-6-astra",
|
|
68
|
+
"reasoning_effort": "high"
|
|
69
|
+
},
|
|
70
|
+
"worker": {
|
|
71
|
+
"model": "gpt-5.6-luna",
|
|
72
|
+
"reasoning_effort": "high"
|
|
73
|
+
}
|
|
59
74
|
}
|
|
60
75
|
]
|
|
61
76
|
},
|
|
62
77
|
"agentic": {
|
|
63
|
-
"description": "One repetition comparing direct baselines with real FlowPilot runtime execution under efficient and balanced profiles.",
|
|
78
|
+
"description": "One repetition comparing direct baselines with real FlowPilot runtime execution under efficient and balanced profiles. Includes Astra/high parent with the real efficient FlowPilot runtime.",
|
|
64
79
|
"repetitions": 1,
|
|
65
80
|
"matrix": [
|
|
66
81
|
{"id": "luna-direct", "strategy": "direct", "model": "gpt-5.6-luna", "reasoning_effort": "high"},
|
|
@@ -83,6 +98,21 @@
|
|
|
83
98
|
"routing_mode": "delegate",
|
|
84
99
|
"parent": {"model": "gpt-5.6-sol", "reasoning_effort": "high"},
|
|
85
100
|
"worker": {"model": "gpt-5.6-luna", "reasoning_effort": "high"}
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"id": "codex-flow-runtime-astra-high",
|
|
104
|
+
"strategy": "runtime",
|
|
105
|
+
"reasoning_policy": "fixed",
|
|
106
|
+
"profile": "efficient",
|
|
107
|
+
"routing_mode": "delegate",
|
|
108
|
+
"parent": {
|
|
109
|
+
"model": "gpt-6-astra",
|
|
110
|
+
"reasoning_effort": "high"
|
|
111
|
+
},
|
|
112
|
+
"worker": {
|
|
113
|
+
"model": "gpt-5.6-luna",
|
|
114
|
+
"reasoning_effort": "high"
|
|
115
|
+
}
|
|
86
116
|
}
|
|
87
117
|
]
|
|
88
118
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codex-flow
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.14
|
|
4
4
|
Summary: Intelligent, Efficient, Adaptive Multi-Agent Strategy Orchestration for Codex
|
|
5
5
|
Home-page: https://github.com/ParsifalC/codex-flow
|
|
6
6
|
Author: Parsifal
|
|
@@ -45,7 +45,7 @@ Dynamic: requires-python
|
|
|
45
45
|
|
|
46
46
|
**智能、高效、自适应的 Codex 多 Agent 策略编排引擎**
|
|
47
47
|
|
|
48
|
-
[](VERSION)
|
|
49
49
|
[](https://github.com/ParsifalC/homebrew-tap)
|
|
50
50
|
[](https://pypi.org/project/codex-flow/)
|
|
51
51
|
[](#-快速安装)
|
|
@@ -256,7 +256,7 @@ codex-flow
|
|
|
256
256
|
|
|
257
257
|
```text
|
|
258
258
|
╭────────────────────────────────────────────────────────────────────╮
|
|
259
|
-
│ 🚀 codex-flow 控制台 (v2.1.
|
|
259
|
+
│ 🚀 codex-flow 控制台 (v2.1.14) │
|
|
260
260
|
│ FlowPilot 智能编排 · 确定性任务遥测 · 本地 Benchmark 验证 │
|
|
261
261
|
╰────────────────────────────────────────────────────────────────────╯
|
|
262
262
|
[1] 🪟 macOS 原生悬浮窗 (overlay widget)
|
|
@@ -55,6 +55,7 @@ benchmark/profiles.json
|
|
|
55
55
|
benchmark/schema.json
|
|
56
56
|
benchmark/tasks.json
|
|
57
57
|
benchmark/prices/gpt-5.6-2026-08-30.json
|
|
58
|
+
benchmark/prices/gpt-6-astra-2026-09-12.json
|
|
58
59
|
codex_flow.egg-info/PKG-INFO
|
|
59
60
|
codex_flow.egg-info/SOURCES.txt
|
|
60
61
|
codex_flow.egg-info/dependency_links.txt
|
|
@@ -176,6 +176,10 @@ def load_jsonl(path: Path) -> list[dict[str, Any]]:
|
|
|
176
176
|
for usage in row["model_usage"]:
|
|
177
177
|
if usage["role"] == "direct":
|
|
178
178
|
raise ValueError(f"{path}:{n}: {row['strategy']} model_usage cannot use direct role")
|
|
179
|
+
# Runtime workers are selected by the planner. The top-level
|
|
180
|
+
# worker fields describe configuration, not observed actors.
|
|
181
|
+
if row["strategy"] == "runtime" and usage["role"] == "worker":
|
|
182
|
+
continue
|
|
179
183
|
expected_model = row["model"] if usage["role"] == "parent" else row["worker_model"]
|
|
180
184
|
expected_effort = row["reasoning_effort"] if usage["role"] == "parent" else row["worker_reasoning_effort"]
|
|
181
185
|
if usage["model"] != expected_model or usage["reasoning_effort"] != expected_effort:
|
|
@@ -11,7 +11,7 @@ from datetime import datetime, timezone
|
|
|
11
11
|
from pathlib import Path
|
|
12
12
|
|
|
13
13
|
ROOT = Path(__file__).resolve().parents[1]
|
|
14
|
-
DEFAULT_PRICE = ROOT / "benchmark/prices/gpt-
|
|
14
|
+
DEFAULT_PRICE = ROOT / "benchmark/prices/gpt-6-astra-2026-09-12.json"
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def run(cmd: list[str], *, check: bool = True, capture: bool = False) -> subprocess.CompletedProcess[str]:
|
|
@@ -35,7 +35,7 @@ def main() -> int:
|
|
|
35
35
|
ap = argparse.ArgumentParser(
|
|
36
36
|
description="Run the built-in codex-flow benchmark using the local Codex login session."
|
|
37
37
|
)
|
|
38
|
-
ap.add_argument("profile", nargs="?", choices=["quick", "full"], default="quick")
|
|
38
|
+
ap.add_argument("profile", nargs="?", choices=["quick", "full", "agentic"], default="quick")
|
|
39
39
|
ap.add_argument("--workspace", default=".codex-flow-benchmark")
|
|
40
40
|
ap.add_argument("--output")
|
|
41
41
|
ap.add_argument("--prices", default=str(DEFAULT_PRICE))
|
|
@@ -79,7 +79,7 @@ def main() -> int:
|
|
|
79
79
|
if disp_output.startswith(home_str):
|
|
80
80
|
disp_output = "~" + disp_output[len(home_str):]
|
|
81
81
|
|
|
82
|
-
budget = "~15M tokens (planning + repairs may increase)" if args.profile == "quick" else "
|
|
82
|
+
budget = "~15M tokens (planning + repairs may increase)" if args.profile == "quick" else f"{planned} runs; usage depends on task execution and repairs"
|
|
83
83
|
|
|
84
84
|
def pad_line(content: str, width: int = 68) -> str:
|
|
85
85
|
pad = max(0, width - len(content))
|
|
@@ -71,6 +71,8 @@ def yes_no(value: bool) -> str:
|
|
|
71
71
|
def composition(row: dict[str, Any]) -> str:
|
|
72
72
|
if row["strategy"] == "direct":
|
|
73
73
|
return f"{row['model']} / {row['reasoning_effort']}"
|
|
74
|
+
if row["strategy"] == "runtime":
|
|
75
|
+
return f"{row['model']} / {row['reasoning_effort']} parent → runtime-selected workers"
|
|
74
76
|
policy = row.get("reasoning_policy", "fixed")
|
|
75
77
|
if policy == "adaptive":
|
|
76
78
|
return f"{row['model']} parent → {row['worker_model']} worker / adaptive"
|
|
@@ -180,6 +182,22 @@ def main() -> int:
|
|
|
180
182
|
f"{pct(item_first, len(items))} | {item_repairs} | {item_reviews} | {item_wall:.1f}s | ${item_cost / len(items):.6f} |"
|
|
181
183
|
)
|
|
182
184
|
|
|
185
|
+
runtime_actors: dict[tuple[str, str, str, str], int] = defaultdict(int)
|
|
186
|
+
for row in rows:
|
|
187
|
+
if row["strategy"] == "runtime":
|
|
188
|
+
for usage in row["model_usage"]:
|
|
189
|
+
key = (row["strategy_id"], usage["role"], usage["model"], usage["reasoning_effort"])
|
|
190
|
+
runtime_actors[key] += usage["calls"]
|
|
191
|
+
if runtime_actors:
|
|
192
|
+
lines.extend([
|
|
193
|
+
"", "## Runtime actor usage", "",
|
|
194
|
+
"Runtime worker configuration may differ from planner-selected actors. The following model/effort values come from recorded usage attribution.",
|
|
195
|
+
"", "| Strategy | Role | Model | Effort | Calls |",
|
|
196
|
+
"| --- | --- | --- | --- | ---: |",
|
|
197
|
+
])
|
|
198
|
+
for (strategy_id, role, model, effort), calls in sorted(runtime_actors.items()):
|
|
199
|
+
lines.append(f"| {strategy_id} | {role} | {model} | {effort} | {calls} |")
|
|
200
|
+
|
|
183
201
|
lines.extend([
|
|
184
202
|
"",
|
|
185
203
|
"## Token efficiency",
|
|
@@ -196,6 +196,20 @@ def parse_usage(jsonl: str) -> dict[str, int]:
|
|
|
196
196
|
return usage
|
|
197
197
|
|
|
198
198
|
|
|
199
|
+
def seed_local_login(destination: Path) -> None:
|
|
200
|
+
"""Seed a private run home without importing global instructions/config."""
|
|
201
|
+
destination.mkdir(parents=True, exist_ok=True)
|
|
202
|
+
login_home = Path(os.environ.get("CODEX_HOME", str(Path.home() / ".codex")))
|
|
203
|
+
login_file = login_home / "auth.json"
|
|
204
|
+
credential = destination / "auth.json"
|
|
205
|
+
if login_file.is_file() and not credential.exists():
|
|
206
|
+
with open(credential, "x", encoding="utf-8", opener=lambda path, flags: os.open(path, flags, 0o600)) as sink:
|
|
207
|
+
sink.write(login_file.read_text(encoding="utf-8"))
|
|
208
|
+
model_cache = login_home / "models_cache.json"
|
|
209
|
+
if model_cache.is_file() and not (destination / "models_cache.json").exists():
|
|
210
|
+
shutil.copyfile(model_cache, destination / "models_cache.json")
|
|
211
|
+
|
|
212
|
+
|
|
199
213
|
def run_codex(
|
|
200
214
|
workdir: Path,
|
|
201
215
|
model: str,
|
|
@@ -208,16 +222,19 @@ def run_codex(
|
|
|
208
222
|
output_schema_path: Path | None = None,
|
|
209
223
|
ignore_user_config: bool = True,
|
|
210
224
|
env: dict[str, str] | None = None,
|
|
225
|
+
writable_dirs: tuple[Path, ...] = (),
|
|
211
226
|
) -> tuple[int, dict[str, int], str, float, str]:
|
|
212
227
|
cmd = [
|
|
213
|
-
"codex", "exec", "--
|
|
228
|
+
"codex", "exec", "--json",
|
|
214
229
|
]
|
|
215
230
|
if ignore_user_config:
|
|
216
|
-
cmd.
|
|
231
|
+
cmd.extend(["--ephemeral", "--ignore-user-config"])
|
|
217
232
|
cmd.extend([
|
|
218
233
|
"--sandbox", sandbox, "--model", model,
|
|
219
234
|
"-c", f'model_reasoning_effort="{effort}"',
|
|
220
235
|
])
|
|
236
|
+
for directory in writable_dirs:
|
|
237
|
+
cmd.extend(["--add-dir", str(directory)])
|
|
221
238
|
if output_schema_path is not None:
|
|
222
239
|
cmd.extend(["--output-schema", str(output_schema_path)])
|
|
223
240
|
if last_message_path is not None:
|
|
@@ -225,20 +242,32 @@ def run_codex(
|
|
|
225
242
|
cmd.extend(["--cd", str(workdir), prompt])
|
|
226
243
|
started = time.monotonic()
|
|
227
244
|
run_env = os.environ.copy()
|
|
245
|
+
if ignore_user_config:
|
|
246
|
+
baseline_home = workdir.parent / ".codex-baseline"
|
|
247
|
+
seed_local_login(baseline_home)
|
|
248
|
+
run_env["CODEX_HOME"] = str(baseline_home)
|
|
228
249
|
if env:
|
|
229
250
|
run_env.update(env)
|
|
230
251
|
try:
|
|
231
|
-
proc = subprocess.run(cmd, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=timeout, env=run_env)
|
|
252
|
+
proc = subprocess.run(cmd, cwd=workdir, text=True, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=timeout, env=run_env)
|
|
232
253
|
elapsed = time.monotonic() - started
|
|
233
254
|
last_message = ""
|
|
234
255
|
if last_message_path is not None and last_message_path.exists():
|
|
235
256
|
last_message = last_message_path.read_text()[-MAX_CAPTURE:]
|
|
236
|
-
|
|
257
|
+
diagnostic = (
|
|
258
|
+
proc.stderr[-MAX_CAPTURE // 4:] + "\n" + proc.stdout[-3 * MAX_CAPTURE // 4:]
|
|
259
|
+
if proc.stderr and proc.stdout else (proc.stderr or proc.stdout)[-MAX_CAPTURE:]
|
|
260
|
+
)
|
|
261
|
+
return proc.returncode, parse_usage(proc.stdout), diagnostic, elapsed, last_message
|
|
237
262
|
except subprocess.TimeoutExpired as exc:
|
|
238
263
|
elapsed = time.monotonic() - started
|
|
239
|
-
stdout = exc.stdout if isinstance(exc.stdout,
|
|
240
|
-
stderr = exc.stderr if isinstance(exc.stderr,
|
|
241
|
-
|
|
264
|
+
stdout = exc.stdout.decode("utf-8", errors="replace") if isinstance(exc.stdout, bytes) else (exc.stdout or "")
|
|
265
|
+
stderr = exc.stderr.decode("utf-8", errors="replace") if isinstance(exc.stderr, bytes) else (exc.stderr or "")
|
|
266
|
+
diagnostic = (
|
|
267
|
+
stderr[-MAX_CAPTURE // 4:] + "\n" + stdout[-3 * MAX_CAPTURE // 4:]
|
|
268
|
+
if stderr and stdout else (stderr or stdout)[-MAX_CAPTURE:]
|
|
269
|
+
)
|
|
270
|
+
return 124, parse_usage(stdout), diagnostic, elapsed, ""
|
|
242
271
|
|
|
243
272
|
|
|
244
273
|
def run_verify(workdir: Path, argv: list[str], timeout: int) -> tuple[bool, str, float]:
|
|
@@ -335,7 +364,7 @@ def build_row(
|
|
|
335
364
|
"repetition": repetition,
|
|
336
365
|
"codex_exit_code": codex_exit,
|
|
337
366
|
"verification_excerpt": verification[-2000:] if not passed else "",
|
|
338
|
-
"diagnostic_excerpt": diagnostic[-
|
|
367
|
+
"diagnostic_excerpt": diagnostic[-MAX_CAPTURE:] if not passed or codex_exit != 0 else "",
|
|
339
368
|
}
|
|
340
369
|
|
|
341
370
|
|
|
@@ -639,6 +668,11 @@ def execute_runtime(
|
|
|
639
668
|
# Pre-authorize hooks for headless non-interactive execution
|
|
640
669
|
authorize_hooks(codex_home)
|
|
641
670
|
|
|
671
|
+
# Reuse file-backed local login without importing the user's routing or
|
|
672
|
+
# plugin configuration. Keep the temporary credential private; the run's
|
|
673
|
+
# TemporaryDirectory removes it together with the isolated runtime.
|
|
674
|
+
seed_local_login(codex_home)
|
|
675
|
+
|
|
642
676
|
runtime_env = {
|
|
643
677
|
"CODEX_HOME": str(codex_home),
|
|
644
678
|
"PATH": f"{bin_dir}:{os.environ.get('PATH', '')}",
|
|
@@ -653,7 +687,7 @@ def execute_runtime(
|
|
|
653
687
|
|
|
654
688
|
codex_exit, usage, diagnostic, elapsed, _ = run_codex(
|
|
655
689
|
workdir, parent_model, parent_effort, runtime_prompt, timeout,
|
|
656
|
-
ignore_user_config=False, env=runtime_env,
|
|
690
|
+
ignore_user_config=False, env=runtime_env, writable_dirs=(codex_home,),
|
|
657
691
|
)
|
|
658
692
|
total_wall += elapsed
|
|
659
693
|
cumulative_codex_usage = empty_usage()
|
|
@@ -677,7 +711,7 @@ def execute_runtime(
|
|
|
677
711
|
)
|
|
678
712
|
codex_exit, usage, diagnostic, elapsed, _ = run_codex(
|
|
679
713
|
workdir, parent_model, parent_effort, repair_prompt, timeout,
|
|
680
|
-
ignore_user_config=False, env=runtime_env,
|
|
714
|
+
ignore_user_config=False, env=runtime_env, writable_dirs=(codex_home,),
|
|
681
715
|
)
|
|
682
716
|
total_wall += elapsed
|
|
683
717
|
add_usage(cumulative_codex_usage, usage)
|
|
@@ -705,15 +739,20 @@ def execute_runtime(
|
|
|
705
739
|
workers = run_data.get("workers")
|
|
706
740
|
if isinstance(workers, dict):
|
|
707
741
|
for w_name, w in workers.items():
|
|
708
|
-
if
|
|
742
|
+
if not isinstance(w, dict):
|
|
743
|
+
continue
|
|
744
|
+
if "review" in str(w.get("agent_type", w_name)).lower():
|
|
709
745
|
review_cycles += 1
|
|
710
746
|
if isinstance(w, dict) and isinstance(w.get("usage"), dict):
|
|
711
747
|
w_u = w["usage"]
|
|
712
748
|
if any(w_u.get(k, 0) > 0 for k in ("input_tokens", "cached_input_tokens", "output_tokens")):
|
|
713
|
-
add_model_usage(
|
|
749
|
+
add_model_usage(
|
|
750
|
+
usage_by_model, "worker", w.get("model") or worker_model,
|
|
751
|
+
w.get("reasoning_effort") or worker_effort, w_u,
|
|
752
|
+
)
|
|
714
753
|
|
|
715
754
|
# Fallback to top-level codex exec usage attributed to parent if telemetry was not populated
|
|
716
|
-
if not usage_by_model:
|
|
755
|
+
if not any(role == "parent" for role, _, _ in usage_by_model):
|
|
717
756
|
add_model_usage(usage_by_model, "parent", parent_model, parent_effort, cumulative_codex_usage)
|
|
718
757
|
|
|
719
758
|
return build_row(
|
|
@@ -799,7 +838,7 @@ def main() -> int:
|
|
|
799
838
|
for repetition in range(1, manifest.get("repetitions", 1) + 1):
|
|
800
839
|
with tempfile.TemporaryDirectory(prefix="codex-flow-bench-") as tmp:
|
|
801
840
|
row = execute_run(
|
|
802
|
-
task, config, Path(tmp), repetition,
|
|
841
|
+
task, config, Path(tmp).resolve(), repetition,
|
|
803
842
|
manifest.get("timeout_seconds", 1800),
|
|
804
843
|
task.get("max_repair_cycles", manifest.get("max_repair_cycles", 2)),
|
|
805
844
|
)
|
|
@@ -16,7 +16,6 @@ FORMULA_PATH = ROOT / "packaging" / "homebrew" / "codex-flow.rb"
|
|
|
16
16
|
TEMPLATE = """class CodexFlow < Formula
|
|
17
17
|
desc "Intelligent, Efficient, Adaptive Multi-Agent Strategy Orchestration for Codex"
|
|
18
18
|
homepage "https://github.com/ParsifalC/codex-flow"
|
|
19
|
-
version "{version}"
|
|
20
19
|
|
|
21
20
|
on_macos do
|
|
22
21
|
if Hardware::CPU.arm?
|
|
@@ -42,7 +41,8 @@ TEMPLATE = """class CodexFlow < Formula
|
|
|
42
41
|
libexec.install Dir["*"]
|
|
43
42
|
bin.write_exec_script libexec/"bin/codex-flow"
|
|
44
43
|
bin.write_exec_script libexec/"bin/codex-flow-mcp"
|
|
45
|
-
|
|
44
|
+
completion = libexec/"completions/codex-flow.bash"
|
|
45
|
+
bash_completion.install completion => "codex-flow" if completion.exist?
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def caveats
|
|
@@ -56,7 +56,7 @@ TEMPLATE = """class CodexFlow < Formula
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
test do
|
|
59
|
-
assert_match "codex-flow", shell_output("#{{bin}}/codex-flow --help"
|
|
59
|
+
assert_match "codex-flow", shell_output("#{{bin}}/codex-flow --help")
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
62
|
"""
|
codex_flow-2.1.13/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2.1.13
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Models/TelemetryData.swift
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Services/TelemetryWatcher.swift
RENAMED
|
File without changes
|
{codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Services/UpdateService.swift
RENAMED
|
File without changes
|
|
File without changes
|
{codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Views/AnalyticsView.swift
RENAMED
|
File without changes
|
{codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Views/AutostartView.swift
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Views/HoverRevealText.swift
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Sources/Views/StrategyModeView.swift
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Tests/OverlayScreenGeometryTests.swift
RENAMED
|
File without changes
|
{codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Tests/TelemetryPhase1ContractTests.swift
RENAMED
|
File without changes
|
|
File without changes
|
{codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Tests/TelemetryQuotaSelectionTests.swift
RENAMED
|
File without changes
|
{codex_flow-2.1.13 → codex_flow-2.1.14}/apps/macos-overlay/Tests/TelemetryWorkerTokenTests.swift
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|