Compare commits
1 Commits
main
...
fix/anthro
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1cac93f844 |
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
||||
os: [macos-15, ubuntu-22.04]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
uses: actions/checkout@v4
|
||||
|
||||
|
||||
- name: Fetch Commander dependency
|
||||
@ -37,7 +37,7 @@ jobs:
|
||||
swift-version: '6.2.1'
|
||||
|
||||
- name: Cache Swift Package Manager
|
||||
uses: actions/cache@v6
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
.build
|
||||
@ -83,7 +83,7 @@ jobs:
|
||||
os: [macos-15]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Fetch Commander dependency
|
||||
shell: bash
|
||||
@ -136,7 +136,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install SwiftLint
|
||||
run: brew install swiftlint
|
||||
|
||||
8
.github/workflows/cross-platform.yml
vendored
8
.github/workflows/cross-platform.yml
vendored
@ -27,7 +27,7 @@ jobs:
|
||||
name: Ubuntu 22.04 LTS
|
||||
container: swift:6.2
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/checkout@v4
|
||||
- name: Fetch Commander dependency
|
||||
shell: bash
|
||||
run: git clone --depth 1 https://github.com/steipete/Commander.git ../Commander
|
||||
@ -56,7 +56,7 @@ jobs:
|
||||
name: Ubuntu 24.04 LTS
|
||||
container: swift:6.2
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/checkout@v4
|
||||
- name: Fetch Commander dependency
|
||||
shell: bash
|
||||
run: git clone --depth 1 https://github.com/steipete/Commander.git ../Commander
|
||||
@ -86,7 +86,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/main'
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Create release info
|
||||
run: |
|
||||
@ -101,7 +101,7 @@ jobs:
|
||||
echo "Total: 4 platform configurations tested in parallel" >> release-info.txt
|
||||
|
||||
- name: Upload release info
|
||||
uses: actions/upload-artifact@v7
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cross-platform-validation
|
||||
path: release-info.txt
|
||||
|
||||
12
.github/workflows/lint.yml
vendored
12
.github/workflows/lint.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
||||
runs-on: macos-15
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Fetch Commander dependency
|
||||
shell: bash
|
||||
@ -28,7 +28,7 @@ jobs:
|
||||
xcode-version: '26.1'
|
||||
|
||||
- name: Cache SwiftLint
|
||||
uses: actions/cache@v6
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.mint
|
||||
@ -69,7 +69,7 @@ jobs:
|
||||
runs-on: macos-15
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Fetch Commander dependency
|
||||
shell: bash
|
||||
@ -81,7 +81,7 @@ jobs:
|
||||
xcode-version: '26.1'
|
||||
|
||||
- name: Cache SwiftFormat
|
||||
uses: actions/cache@v6
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.mint
|
||||
@ -111,7 +111,7 @@ jobs:
|
||||
runs-on: macos-15
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Fetch Commander dependency
|
||||
shell: bash
|
||||
@ -158,7 +158,7 @@ jobs:
|
||||
runs-on: macos-15
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Fetch Commander dependency
|
||||
shell: bash
|
||||
|
||||
12
.github/workflows/test.yml
vendored
12
.github/workflows/test.yml
vendored
@ -25,7 +25,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Fetch Commander dependency
|
||||
shell: bash
|
||||
@ -37,7 +37,7 @@ jobs:
|
||||
xcode-version: '26.1'
|
||||
|
||||
- name: Cache Swift Package Manager
|
||||
uses: actions/cache@v6
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .build
|
||||
key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }}
|
||||
@ -75,7 +75,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Fetch Commander dependency
|
||||
shell: bash
|
||||
@ -87,7 +87,7 @@ jobs:
|
||||
swift-version: ${{ matrix.swift-version }}
|
||||
|
||||
- name: Cache Swift Package Manager
|
||||
uses: actions/cache@v6
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .build
|
||||
key: ${{ runner.os }}-spm-${{ matrix.swift-version }}-${{ hashFiles('**/Package.resolved') }}
|
||||
@ -122,7 +122,7 @@ jobs:
|
||||
runs-on: macos-15
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Fetch Commander dependency
|
||||
shell: bash
|
||||
@ -155,7 +155,7 @@ jobs:
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Fetch Commander dependency
|
||||
shell: bash
|
||||
|
||||
@ -15,7 +15,7 @@ All notable changes to the Tachikoma project will be documented in this file.
|
||||
- Removed stale direct model support for retired or non-canonical IDs including GPT-5.1/5.2/pseudo-thinking models, deprecated Claude Sonnet/Opus 4 snapshots, Grok 2/3/4-fast rows, old Groq Llama/Mixtral/Gemma aliases, stale Mistral aliases, and invalid LM Studio `current`.
|
||||
|
||||
### Fixed
|
||||
- OpenAI `gpt-5-chat-latest` now preserves its distinct model identity, appears in model listings, and applies GPT-5 parameter filtering instead of being rewritten to `chat-latest`.
|
||||
- OpenAI `gpt-5-chat-latest` now preserves its distinct model identity instead of being rewritten to `chat-latest`.
|
||||
- SwiftPM consumers now resolve Commander from the package URL instead of accidentally inheriting a sibling local checkout.
|
||||
- Ollama model parsing now preserves explicit custom vision model IDs such as `qwen2.5vl:3b` instead of falling back to `llama3.3` (#16).
|
||||
- Auth resolution now snapshots environment-ignore state consistently, preventing parallel tests and concurrent callers from falling back to stored OpenRouter credentials when an environment override is present.
|
||||
|
||||
@ -1,15 +1,6 @@
|
||||
{
|
||||
"originHash" : "12a454cd38a6ae2519d652cc0872f7f18feb64690ce83d1507bae6db71c1841c",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "commander",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/steipete/Commander.git",
|
||||
"state" : {
|
||||
"revision" : "ae2ce746b386ff94b26648cfe5625cfa8d02639b",
|
||||
"version" : "0.2.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "eventsource",
|
||||
"kind" : "remoteSourceControl",
|
||||
@ -33,8 +24,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-asn1.git",
|
||||
"state" : {
|
||||
"revision" : "a9a5efd40eaf558a2bcd48d64b1d1646be686008",
|
||||
"version" : "1.7.1"
|
||||
"revision" : "eb50cbd14606a9161cbc5d452f18797c90ef0bab",
|
||||
"version" : "1.7.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -42,8 +33,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-async-algorithms.git",
|
||||
"state" : {
|
||||
"revision" : "d0b4a06d0f173a2f3be27d3ea21b3c3aa18db440",
|
||||
"version" : "1.1.4"
|
||||
"revision" : "9d349bcc328ac3c31ce40e746b5882742a0d1272",
|
||||
"version" : "1.1.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -60,8 +51,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-collections",
|
||||
"state" : {
|
||||
"revision" : "a0cb0954ecb21e4e31b0070e6ed5674e8556685a",
|
||||
"version" : "1.6.0"
|
||||
"revision" : "6675bc0ff86e61436e615df6fc5174e043e57924",
|
||||
"version" : "1.4.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -87,8 +78,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-log.git",
|
||||
"state" : {
|
||||
"revision" : "92448c359f00ebe36ae97d3bd9086f13c7692b5a",
|
||||
"version" : "1.13.2"
|
||||
"revision" : "5073617dac96330a486245e4c0179cb0a6fd2256",
|
||||
"version" : "1.12.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -96,8 +87,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-nio.git",
|
||||
"state" : {
|
||||
"revision" : "a8e036cb8628fcc1ff67dfec6ce8168617172c9b",
|
||||
"version" : "2.101.1"
|
||||
"revision" : "f71c8d2a5e74a2c6d11a0fbe324774b5d6084237",
|
||||
"version" : "2.99.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -114,8 +105,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/modelcontextprotocol/swift-sdk.git",
|
||||
"state" : {
|
||||
"revision" : "a0ae212ebf6eab5f754c3129608bc5557637e605",
|
||||
"version" : "0.12.1"
|
||||
"revision" : "6132fd4b5b4217ce4717c4775e4607f5c3120129",
|
||||
"version" : "0.12.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -132,8 +123,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-system.git",
|
||||
"state" : {
|
||||
"revision" : "7502b711c92a17741fa625d722b0ccbd595d8ed1",
|
||||
"version" : "1.7.2"
|
||||
"revision" : "7c6ad0fc39d0763e0b699210e4124afd5041c5df",
|
||||
"version" : "1.6.4"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@ -433,7 +433,7 @@ public func streamText(
|
||||
}
|
||||
}
|
||||
|
||||
if buffersUntilDone, !didReceiveTerminal {
|
||||
if buffersUntilDone, !didReceiveTerminal, !bufferedDeltas.isEmpty {
|
||||
throw TachikomaError.apiError("Stream ended before provider completion status was received")
|
||||
}
|
||||
|
||||
@ -1049,10 +1049,7 @@ extension LanguageModel {
|
||||
fallbackContent.append(.text(text))
|
||||
}
|
||||
fallbackContent.append(contentsOf: missingToolCalls.map { .toolCall($0) })
|
||||
let fallbackMetadata = needsFallbackBoundary
|
||||
? MessageMetadata(customData: ["tachikoma.internal.boundary": "reasoning_only"])
|
||||
: nil
|
||||
history.append(ModelMessage(role: .assistant, content: fallbackContent, metadata: fallbackMetadata))
|
||||
history.append(ModelMessage(role: .assistant, content: fallbackContent))
|
||||
return history
|
||||
}
|
||||
|
||||
|
||||
@ -242,7 +242,6 @@ public final class ModelCapabilityRegistry: @unchecked Sendable {
|
||||
)
|
||||
|
||||
self.capabilities["openai:chat-latest"] = gpt5Capabilities
|
||||
self.capabilities["openai:gpt-5-chat-latest"] = gpt5Capabilities
|
||||
self.capabilities["openai:gpt-5.5"] = gpt5Capabilities
|
||||
self.capabilities["openai:gpt-5.4"] = gpt5Capabilities
|
||||
self.capabilities["openai:gpt-5.4-mini"] = gpt5Capabilities
|
||||
|
||||
@ -57,7 +57,6 @@ public enum LanguageModel: Sendable, CustomStringConvertible, Hashable {
|
||||
public static var allCases: [OpenAI] {
|
||||
[
|
||||
.chatLatest,
|
||||
.gpt5ChatLatest,
|
||||
.gpt55,
|
||||
.gpt54,
|
||||
.gpt54Mini,
|
||||
|
||||
@ -1258,29 +1258,6 @@ struct GenerationTests {
|
||||
.canonical("https://example.test"))
|
||||
}
|
||||
|
||||
@Test
|
||||
func `GenerateText tags fallback reasoning-only boundary for Anthropic-compatible Fable`() async throws {
|
||||
let providerResponse = ProviderResponse(
|
||||
text: "",
|
||||
finishReason: .stop,
|
||||
reasoning: [ProviderReasoningBlock(text: "private", signature: "sig")],
|
||||
)
|
||||
let config = TachikomaConfiguration(loadFromEnvironment: false)
|
||||
config.setProviderFactoryOverride { _, _ in StaticProvider(response: providerResponse) }
|
||||
|
||||
let result = try await generateText(
|
||||
model: .anthropicCompatible(modelId: "claude-fable-5", baseURL: "https://example.test"),
|
||||
messages: [.user("hi")],
|
||||
configuration: config,
|
||||
)
|
||||
|
||||
#expect(result.messages.count == 3)
|
||||
#expect(result.messages[1].channel == .thinking)
|
||||
#expect(result.messages[2].role == .assistant)
|
||||
#expect(result.messages[2].content == [.text("")])
|
||||
#expect(result.messages[2].metadata?.customData?["tachikoma.internal.boundary"] == "reasoning_only")
|
||||
}
|
||||
|
||||
@Test
|
||||
func `GenerateText tags fallback reasoning for direct custom Fable`() async throws {
|
||||
let provider = StaticProvider(
|
||||
@ -1506,36 +1483,6 @@ struct GenerationTests {
|
||||
#expect(operation.usage.outputTokens > 0)
|
||||
}
|
||||
|
||||
@Test
|
||||
func `StreamText buffered mode fails when provider ends without terminal status`() async throws {
|
||||
let config = TachikomaConfiguration(loadFromEnvironment: false)
|
||||
config.setProviderFactoryOverride { _, _ in
|
||||
StaticProvider(
|
||||
response: ProviderResponse(text: "", finishReason: .stop),
|
||||
capabilities: ModelCapabilities(supportsStreaming: true),
|
||||
streamDeltas: [],
|
||||
)
|
||||
}
|
||||
|
||||
let result = try await streamText(
|
||||
model: .openaiCompatible(modelId: "compatible-model", baseURL: "https://example.test"),
|
||||
messages: [.user("hi")],
|
||||
settings: GenerationSettings(streamBuffering: .untilTerminal),
|
||||
configuration: config,
|
||||
)
|
||||
|
||||
do {
|
||||
for try await _ in result.stream {}
|
||||
Issue.record("Expected missing terminal status error")
|
||||
} catch let error as TachikomaError {
|
||||
guard case let .apiError(message) = error else {
|
||||
Issue.record("Expected apiError, got \(error)")
|
||||
return
|
||||
}
|
||||
#expect(message.contains("provider completion status"))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
func `StreamText stop conditions ignore reasoning deltas`() async throws {
|
||||
let config = TachikomaConfiguration(loadFromEnvironment: false)
|
||||
|
||||
@ -6,7 +6,6 @@ struct LanguageModelCoverageTests {
|
||||
func `OpenAI enum exposes properties`() {
|
||||
let models = LanguageModel.OpenAI.allCases
|
||||
#expect(!models.isEmpty)
|
||||
#expect(models.contains(.gpt5ChatLatest))
|
||||
for model in models {
|
||||
#expect(!model.modelId.isEmpty)
|
||||
_ = model.supportsVision
|
||||
|
||||
@ -7,7 +7,6 @@ enum ModelCapabilitiesTests {
|
||||
@Test
|
||||
func `GPT-5 models exclude temperature and topP`() {
|
||||
let models: [LanguageModel] = [
|
||||
.openai(.gpt5ChatLatest),
|
||||
.openai(.gpt55),
|
||||
.openai(.gpt54),
|
||||
.openai(.gpt54Mini),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user