- ReplayEvent: new .escalationAttempt(turnId:kind:) case with .t1ToT2 EscalationKind (D-02 marker, distinct from AGENT-09 stream_truncated) - ReplayEventKind: new .escalationAttempt = "escalation_attempt" rawvalue - AgentOrchestrator: constructor gains optional visionRouter: VisionRouter? = nil - runTurn pre-stream: route image-bearing turns through VisionRouter, swap provider, track imageBearingTurns (D-01, D-16) - runTurnLoop: multimodal stream overload for image-bearing turns; assistantTextSoFar accumulator on .textDelta - runTurnLoop .endTurn arm: post-response evaluatePostResponse hook, .escalateToT2 → discard T1 message, swap to T2, continue outer (WARNING-3 LOCKED labeled-loop strategy); records .escalationAttempt under SAME turnId (D-02) - BLOCKER-2: voiceOriginatedTurns Set<TurnID> + recordVoiceTurn(_:) populator + turnSourceWasVoice(_:) public accessor (Plan 4 voice subscriber will gate emitTurnEnded on this) - turnHadImage(_:) public accessor (Plan 2 frame-attach release subscriber consumer) - AgentCore + Replay + MCP packages bumped from .v13 to .v14 (cascade — JarvisVision is .v14, project deployment target was already 14.0) - MockLLMProvider extended with multimodal stream overload + RecordedCall.images - 6 AgentOrchestratorVisionDispatchTests + 3 AgentOrchestratorVoiceTurnTrackingTests + 3 EscalationAttemptMarkerTests - All 63 existing AgentOrchestratorTests still pass; all 30 Replay tests pass; orchestrator-events single-consumer grep gate exits 0 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
113 lines
4.8 KiB
Swift
113 lines
4.8 KiB
Swift
// swift-tools-version:6.0
|
|
import PackageDescription
|
|
|
|
let package = Package(
|
|
name: "AgentCore",
|
|
// Plan 09-02 — bumped from .v13 to .v14 to match JarvisVision (Plan 07-04).
|
|
// AgentOrchestrator now depends on JarvisVision (D-01 vision-dispatch),
|
|
// and SPM rejects a v13 library depending on a v14 product. AgentCore +
|
|
// AgentOrchestrator have no API surface that's macOS-13-specific.
|
|
platforms: [.macOS(.v14)],
|
|
products: [
|
|
.library(name: "AgentCore", targets: ["AgentCore"]),
|
|
.library(name: "AnthropicProvider", targets: ["AnthropicProvider"]),
|
|
.library(name: "OllamaProvider", targets: ["OllamaProvider"]),
|
|
.library(name: "AgentOrchestrator", targets: ["AgentOrchestrator"]),
|
|
],
|
|
dependencies: [
|
|
.package(path: "../Keychain"),
|
|
.package(path: "../Logging"),
|
|
.package(path: "../Config"),
|
|
.package(path: "../Replay"),
|
|
// Plan 09-02 — AgentOrchestrator now dispatches image-bearing turns
|
|
// through VisionRouter (D-01). Vision already depends on AgentCore,
|
|
// so AgentOrchestrator → Vision → AgentCore is acyclic (Vision
|
|
// does NOT depend on AgentOrchestrator — VISION-03 invariant).
|
|
.package(path: "../Vision"),
|
|
// Plan 05-05 deviation (Rule 3, blocking): AgentOrchestrator
|
|
// sources `import Logging` (swift-log Logger) directly. Same fix
|
|
// pattern as Replay's Package.swift — the Xcode framework
|
|
// linker is stricter than SPM's transitive visibility.
|
|
.package(url: "https://github.com/apple/swift-log.git", from: "1.5.0"),
|
|
],
|
|
targets: [
|
|
// Core protocol surface — provider-agnostic.
|
|
.target(
|
|
name: "AgentCore",
|
|
dependencies: [
|
|
.product(name: "JarvisLogging", package: "Logging"),
|
|
.product(name: "Config", package: "Config"),
|
|
],
|
|
swiftSettings: [.swiftLanguageMode(.v6)]
|
|
),
|
|
// Anthropic Messages API provider — hand-rolled URLSession + SSE.
|
|
.target(
|
|
name: "AnthropicProvider",
|
|
dependencies: [
|
|
"AgentCore",
|
|
.product(name: "Keychain", package: "Keychain"),
|
|
.product(name: "JarvisLogging", package: "Logging"),
|
|
],
|
|
swiftSettings: [.swiftLanguageMode(.v6)]
|
|
),
|
|
// Ollama provider — placeholder in Wave 1; filled in Plan 04-02.
|
|
.target(
|
|
name: "OllamaProvider",
|
|
dependencies: [
|
|
"AgentCore",
|
|
.product(name: "JarvisLogging", package: "Logging"),
|
|
],
|
|
swiftSettings: [.swiftLanguageMode(.v6)]
|
|
),
|
|
// Turn-lifecycle actor — Plan 04-04. Lives in its own target so it
|
|
// can depend on Replay (which depends on AgentCore) without
|
|
// introducing an SPM cycle. Plan 04-04's `files_modified` listed
|
|
// these files under Sources/AgentCore/, but the literal layout
|
|
// would have created Replay → AgentCore → Replay. Rule 3
|
|
// deviation: split into AgentOrchestrator target.
|
|
.target(
|
|
name: "AgentOrchestrator",
|
|
dependencies: [
|
|
"AgentCore",
|
|
.product(name: "JarvisLogging", package: "Logging"),
|
|
.product(name: "Config", package: "Config"),
|
|
.product(name: "Replay", package: "Replay"),
|
|
// Plan 09-02 — visionRouter dispatch + post-response escalation.
|
|
.product(name: "JarvisVision", package: "Vision"),
|
|
.product(name: "Logging", package: "swift-log"),
|
|
],
|
|
swiftSettings: [.swiftLanguageMode(.v6)]
|
|
),
|
|
.testTarget(
|
|
name: "AgentCoreTests",
|
|
dependencies: ["AgentCore"],
|
|
swiftSettings: [.swiftLanguageMode(.v6)]
|
|
),
|
|
.testTarget(
|
|
name: "AnthropicProviderTests",
|
|
dependencies: ["AnthropicProvider", "AgentCore"],
|
|
resources: [.process("Fixtures")],
|
|
swiftSettings: [.swiftLanguageMode(.v6)]
|
|
),
|
|
.testTarget(
|
|
name: "OllamaProviderTests",
|
|
dependencies: ["OllamaProvider", "AgentCore"],
|
|
resources: [.process("Fixtures")],
|
|
swiftSettings: [.swiftLanguageMode(.v6)]
|
|
),
|
|
.testTarget(
|
|
name: "AgentOrchestratorTests",
|
|
dependencies: [
|
|
"AgentOrchestrator",
|
|
"AgentCore",
|
|
.product(name: "Config", package: "Config"),
|
|
.product(name: "Replay", package: "Replay"),
|
|
// Plan 09-02 — vision-dispatch + voice-tracking tests use
|
|
// VisionRouter live (no separate mock surface).
|
|
.product(name: "JarvisVision", package: "Vision"),
|
|
],
|
|
swiftSettings: [.swiftLanguageMode(.v6)]
|
|
),
|
|
]
|
|
)
|