Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion Cotabby.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
3CF1A4E39F24917DF0470A7D /* PromptPolicyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4696A84D17890B154533A08F /* PromptPolicyTests.swift */; };
4134ADBE464D00BB748BD9AE /* GeneralPaneView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07480CE96ED0EBD94817C6B1 /* GeneralPaneView.swift */; };
4190F8A76196B16ED94D0A55 /* VisualContextModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE97A8169438D593C6C23412 /* VisualContextModels.swift */; };
429CE592897D8A952F2916C3 /* ConfidenceSuppressionPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BD71ECC2AE4821B643E0935 /* ConfidenceSuppressionPolicy.swift */; };
42D40F37086294D0E58200C5 /* GhostFontSizeStabilizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9458F0820B3161FE9CF1DDAF /* GhostFontSizeStabilizer.swift */; };
4531645066A73971EB2A5FA1 /* EmojiCatalog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AC3BF78835C8F2C315932F1 /* EmojiCatalog.swift */; };
46F341472191BC451B6BF6B5 /* SuggestionRequestFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE858CB1E687E3CEB8FDD5B /* SuggestionRequestFactory.swift */; };
Expand Down Expand Up @@ -121,6 +122,7 @@
76FD91607794883F8E121450 /* CaretGeometrySelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3C84377F352140759B448C9 /* CaretGeometrySelector.swift */; };
78FAE5DB691A1B71042B9D20 /* AboutPaneView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3FA53BBC3D81503C1D17477 /* AboutPaneView.swift */; };
7B6A63F5DCC2C163CDFD2A5C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BC4F887528AE74AC0DD30314 /* Assets.xcassets */; };
7C36DBA762E19C8C31676D44 /* MidWordContinuationPolicyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1274F897631B1B3A835D157F /* MidWordContinuationPolicyTests.swift */; };
7C94725B4837DEC9ECF1BC54 /* CompletionRenderMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A03E565A11581FD2150B142 /* CompletionRenderMode.swift */; };
7D6BB9AF72F7076A4E5EE96F /* DownloadableModelCatalogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB5C2AE9A7E55495D26AD074 /* DownloadableModelCatalogView.swift */; };
7E9413CE7C999C4612348248 /* SuggestionSessionReconcilerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C8F07AC52C7A482F5FE34C5 /* SuggestionSessionReconcilerTests.swift */; };
Expand All @@ -142,6 +144,7 @@
90DC9508F27F712EB61EEB06 /* PermissionReminderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 656F58E56FE9BC087B6F1D33 /* PermissionReminderView.swift */; };
91C27021750AC03AA4A0115A /* HuggingFaceAPIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110CB0B53016644EF7840301 /* HuggingFaceAPIClient.swift */; };
91D1F16B8C5DA281D4B7F699 /* CustomRulesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD752451330486FE270018B0 /* CustomRulesTests.swift */; };
91D8189EFCD1BA992EA6F038 /* ConfidenceSuppressionPolicyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06FF2B0A3094A952A8EBA9B5 /* ConfidenceSuppressionPolicyTests.swift */; };
924489CEE8171F7AD8579D71 /* FocusDebugOverlayController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F5E263AB69029D5E13D5EE8 /* FocusDebugOverlayController.swift */; };
934885ACC2DEA20B27F10948 /* PromptContextSanitizerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D80CC2CCAAFE3F23FB8C37A /* PromptContextSanitizerTests.swift */; };
96498E097A5899AFC9F0C853 /* EmojiCatalogMatcherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 292DC9D4D9D5D26AE882E39B /* EmojiCatalogMatcherTests.swift */; };
Expand All @@ -150,6 +153,7 @@
98E2E14A069384C1088CDB44 /* PromptContextSanitizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA4B45B91D4DEAC979C3113E /* PromptContextSanitizer.swift */; };
9ABF75CDA78B27453C3F5B34 /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 264CA64B2AB1611F82E5B760 /* WelcomeView.swift */; };
9ADFFF634912F638D079E1C7 /* SentenceBoundaryClassifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4B56C250DDEF3E81F9DCBD7 /* SentenceBoundaryClassifier.swift */; };
9CEBD6AF4405F1BBE0E3D16C /* MidWordContinuationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 357C18383B047F24A531BDCD /* MidWordContinuationPolicy.swift */; };
9F2FDCABCC941CBECAA3B4AB /* CotabbyInference in Frameworks */ = {isa = PBXBuildFile; productRef = 48A46AD6B613CF06072603E4 /* CotabbyInference */; };
A0657CE0488F69F0BD559CBC /* SuggestionCoordinator+Acceptance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72B13136DF7318F3E96DF0D3 /* SuggestionCoordinator+Acceptance.swift */; };
A0BB87E3665EF6C209034798 /* GhostSuggestionLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AD3F4F9FBE82007E4E15F58 /* GhostSuggestionLayoutTests.swift */; };
Expand Down Expand Up @@ -246,6 +250,7 @@
04D853218B0A77B0CE090828 /* BrowserAppDetectorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserAppDetectorTests.swift; sourceTree = "<group>"; };
04E25414C307A20B6F9F20EC /* FocusSnapshotResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FocusSnapshotResolver.swift; sourceTree = "<group>"; };
050D929E13BE52E6282B64D2 /* VisualContextStartCoalescerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisualContextStartCoalescerTests.swift; sourceTree = "<group>"; };
06FF2B0A3094A952A8EBA9B5 /* ConfidenceSuppressionPolicyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfidenceSuppressionPolicyTests.swift; sourceTree = "<group>"; };
07480CE96ED0EBD94817C6B1 /* GeneralPaneView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralPaneView.swift; sourceTree = "<group>"; };
0850B07CCDBA67C756C6EC59 /* ShortcutConflictTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutConflictTests.swift; sourceTree = "<group>"; };
09FADF683BE7B3558377FA76 /* FocusPollBackoff.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FocusPollBackoff.swift; sourceTree = "<group>"; };
Expand All @@ -255,12 +260,14 @@
0D80CC2CCAAFE3F23FB8C37A /* PromptContextSanitizerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromptContextSanitizerTests.swift; sourceTree = "<group>"; };
0F5E263AB69029D5E13D5EE8 /* FocusDebugOverlayController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FocusDebugOverlayController.swift; sourceTree = "<group>"; };
110CB0B53016644EF7840301 /* HuggingFaceAPIClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HuggingFaceAPIClient.swift; sourceTree = "<group>"; };
1274F897631B1B3A835D157F /* MidWordContinuationPolicyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MidWordContinuationPolicyTests.swift; sourceTree = "<group>"; };
12DD19BCE610808F1E38702D /* PermissionOverlayTrackerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PermissionOverlayTrackerTests.swift; sourceTree = "<group>"; };
1441B2D89DAE6878DAD11F17 /* EmojiMatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiMatcher.swift; sourceTree = "<group>"; };
18D990E515E1AE4F312F4E95 /* BundledRuntimeLocatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundledRuntimeLocatorTests.swift; sourceTree = "<group>"; };
19BE12C28A4AB8A4A58C2FF7 /* SettingsPaneScaffold.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsPaneScaffold.swift; sourceTree = "<group>"; };
19DB9558F4D3AFB108D71649 /* SuggestionStateHelperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestionStateHelperTests.swift; sourceTree = "<group>"; };
1A8414BEB7E34F57607E37FE /* EmojiVariantResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiVariantResolver.swift; sourceTree = "<group>"; };
1BD71ECC2AE4821B643E0935 /* ConfidenceSuppressionPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfidenceSuppressionPolicy.swift; sourceTree = "<group>"; };
1CE61E74928C221B8BB261C6 /* SuggestionTextColorCodec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestionTextColorCodec.swift; sourceTree = "<group>"; };
1D00A031C0D9CF2A7A2330D9 /* PermissionDragSourceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PermissionDragSourceView.swift; sourceTree = "<group>"; };
1E0513E3B23937B099A3CFF2 /* WordCountFormatterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordCountFormatterTests.swift; sourceTree = "<group>"; };
Expand All @@ -287,6 +294,7 @@
335BF59EE80F3A0143B79740 /* GhostFontSizeStabilizerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GhostFontSizeStabilizerTests.swift; sourceTree = "<group>"; };
3384FD33776960103D6E22A9 /* EmojiPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerView.swift; sourceTree = "<group>"; };
352AF5B2834FEE1F597394E4 /* ApplicationBundleMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationBundleMetadata.swift; sourceTree = "<group>"; };
357C18383B047F24A531BDCD /* MidWordContinuationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MidWordContinuationPolicy.swift; sourceTree = "<group>"; };
3609CC88A5280B3AA40414DF /* SuggestionAvailabilityEvaluator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestionAvailabilityEvaluator.swift; sourceTree = "<group>"; };
384FBCF5D7A3A446C5BE2B8D /* SuggestionEngineRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestionEngineRouter.swift; sourceTree = "<group>"; };
386C98FFCF76EC1C8C7E82BB /* SuggestionModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestionModels.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -680,6 +688,7 @@
EFD89799BB82AF7A92559AEB /* ClipboardContentDistillerTests.swift */,
90B0D133AB77A2503FB08827 /* ClipboardRelevanceFilterTests.swift */,
D504BEB224E0C176F5FCFF6E /* CompletionRenderModePolicyTests.swift */,
06FF2B0A3094A952A8EBA9B5 /* ConfidenceSuppressionPolicyTests.swift */,
AF1E065C7FFB697FCEB2FA5C /* CotabbyTestFixtures.swift */,
AD752451330486FE270018B0 /* CustomRulesTests.swift */,
C1C5DE0F3FF63545000E2453 /* DisplayCoordinateConverterTests.swift */,
Expand All @@ -704,6 +713,7 @@
5807E8508D9355D0271A00C5 /* LaunchAtLoginStateTests.swift */,
3009812A35A1CDEF16295AB7 /* LlamaPromptRendererTests.swift */,
52BAFA2F989C3C4F7FB892B5 /* MarkerSelectionSynthesizerTests.swift */,
1274F897631B1B3A835D157F /* MidWordContinuationPolicyTests.swift */,
FC83D14A7557BC0196E59007 /* MirrorOverlayLayoutTests.swift */,
03766F6253FF17639230C0F6 /* ModelAndPresentationValueTests.swift */,
A829F28F01FAE76CA7244BBC /* ModelFileValidatorTests.swift */,
Expand Down Expand Up @@ -827,6 +837,7 @@
96495E4147D828C0B1B22765 /* ClipboardContentDistiller.swift */,
D3A2AC525DC664DB540D4F19 /* ClipboardRelevanceFilter.swift */,
53CF416511099C6818110F01 /* CompletionRenderModePolicy.swift */,
1BD71ECC2AE4821B643E0935 /* ConfidenceSuppressionPolicy.swift */,
C7B2D34A6F3AC9DFD61350F7 /* CotabbyDebugOptions.swift */,
29ED42C4BDD0C521101AF95E /* DeviceInfo.swift */,
74BD1D4DB27D5D96D1E06096 /* DisplayCoordinateConverter.swift */,
Expand All @@ -849,6 +860,7 @@
B5679E08C9A09065531C37B5 /* LlamaPromptRenderer.swift */,
8D610FCA3A97249DCCE7D0B8 /* LLMIOFileHandler.swift */,
A863F41C0C03D7B4AC5DC002 /* MarkerSelectionSynthesizer.swift */,
357C18383B047F24A531BDCD /* MidWordContinuationPolicy.swift */,
54150A507B03221F137D539B /* MirrorOverlayLayout.swift */,
24F613F0E2F7046E6532A09C /* OnboardingTemplateFeatureList.swift */,
FA878B447441BB4F3E327CC8 /* OnboardingTemplateRecommender.swift */,
Expand Down Expand Up @@ -1010,6 +1022,7 @@
157A55EB796BEB7819B90D5D /* ClipboardRelevanceFilter.swift in Sources */,
7C94725B4837DEC9ECF1BC54 /* CompletionRenderMode.swift in Sources */,
3985F0F2B3178DBB945B1064 /* CompletionRenderModePolicy.swift in Sources */,
429CE592897D8A952F2916C3 /* ConfidenceSuppressionPolicy.swift in Sources */,
8B2DFC860803C0A7C4D34A36 /* ContextBuffer.swift in Sources */,
AA2E09FF7E430D66ECA8ECD5 /* CotabbyApp.swift in Sources */,
FCC571EC239846F06007BFCA /* CotabbyAppEnvironment.swift in Sources */,
Expand Down Expand Up @@ -1074,6 +1087,7 @@
0333B3CE8F189DD1BEC4AD26 /* MenuBarSections.swift in Sources */,
AECC7289DA796B071B4FE3C0 /* MenuBarStatusLabelView.swift in Sources */,
5E92E3C1EB41D482FC06BC52 /* MenuBarView.swift in Sources */,
9CEBD6AF4405F1BBE0E3D16C /* MidWordContinuationPolicy.swift in Sources */,
31515DDD173535C4AC777853 /* MirrorOverlayLayout.swift in Sources */,
2F227738D7834B1A7A81D1D6 /* ModelDownloadManager.swift in Sources */,
317883210D1D1D5CD654E562 /* ModelFileValidator.swift in Sources */,
Expand Down Expand Up @@ -1160,6 +1174,7 @@
8865B95FE84198D70390DF80 /* ClipboardContentDistillerTests.swift in Sources */,
BFCA7FAFDAEBF586AB615567 /* ClipboardRelevanceFilterTests.swift in Sources */,
25F91CEF38400FD1ADB6B1AF /* CompletionRenderModePolicyTests.swift in Sources */,
91D8189EFCD1BA992EA6F038 /* ConfidenceSuppressionPolicyTests.swift in Sources */,
5E10EFC426217CB7218A5847 /* CotabbyTestFixtures.swift in Sources */,
91D1F16B8C5DA281D4B7F699 /* CustomRulesTests.swift in Sources */,
56611BA0087710277140E9E6 /* DisplayCoordinateConverterTests.swift in Sources */,
Expand All @@ -1184,6 +1199,7 @@
E27E6377D36D4981301568DD /* LaunchAtLoginStateTests.swift in Sources */,
190C571B3CDFE117F4D15484 /* LlamaPromptRendererTests.swift in Sources */,
87806DE08881D11F2608A13D /* MarkerSelectionSynthesizerTests.swift in Sources */,
7C36DBA762E19C8C31676D44 /* MidWordContinuationPolicyTests.swift in Sources */,
14D77F0B8A195AC2FA8D24A9 /* MirrorOverlayLayoutTests.swift in Sources */,
25D4FC8D191A50F63E6391F9 /* ModelAndPresentationValueTests.swift in Sources */,
65478B0DABF5460C32D4C458 /* ModelFileValidatorTests.swift in Sources */,
Expand Down Expand Up @@ -1519,7 +1535,7 @@
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/FuJacob/cotabbyinference.git";
requirement = {
branch = main;
branch = "feat/generation-quality-controls";
kind = branch;
};
};
Expand Down
9 changes: 9 additions & 0 deletions Cotabby/Models/LlamaRuntimeModels.swift
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,15 @@ struct LlamaGenerationOptions: Equatable, Sendable {
let repetitionPenalty: Double
var seed: UInt32?

/// Masks line-break tokens so single-line fields never receive a multi-line completion.
var singleLine: Bool = false
/// Constrains the first generated token to continue the current word (mid-word carets only).
var forceWordContinuation: Bool = false

/// Average per-token log-probability below which a completion is suppressed as low-confidence.
/// Defaults to -infinity, which disables suppression entirely.
var confidenceFloor: Double = -.infinity

static func summary(maxPredictionTokens: Int, temperature: Double) -> LlamaGenerationOptions {
LlamaGenerationOptions(
maxPredictionTokens: maxPredictionTokens,
Expand Down
29 changes: 28 additions & 1 deletion Cotabby/Services/Runtime/LlamaRuntimeCore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ nonisolated final class LlamaRuntimeCore: @unchecked Sendable {

var generatedText = ""
var tokensGenerated = 0
var sumLogprob = 0.0
var stopReason = "budget_exhausted"

for _ in 0 ..< options.maxPredictionTokens {
Expand All @@ -216,6 +217,7 @@ nonisolated final class LlamaRuntimeCore: @unchecked Sendable {
let piece = Self.extractPiece(result)
generatedText += piece
tokensGenerated += 1
sumLogprob += Double(result.logprob)
}

CotabbyLogger.runtime.debug(
Expand All @@ -228,6 +230,23 @@ nonisolated final class LlamaRuntimeCore: @unchecked Sendable {
]
)

// Confidence suppression: drop completions the model itself was unsure about. Disabled by
// default (confidenceFloor == -infinity); the KV-trim defer above still runs on early return.
if tokensGenerated > 0,
ConfidenceSuppressionPolicy.shouldSuppress(
averageLogprob: sumLogprob / Double(tokensGenerated),
floor: options.confidenceFloor
) {
CotabbyLogger.runtime.debug(
"Suppressed low-confidence completion",
metadata: [
"tokens_generated": .stringConvertible(tokensGenerated),
"avg_logprob": .stringConvertible(sumLogprob / Double(tokensGenerated))
]
)
return ""
}

return generatedText
}

Expand Down Expand Up @@ -387,6 +406,9 @@ nonisolated final class LlamaRuntimeCore: @unchecked Sendable {

let remaining = Array(promptTokens[reusableTokenCount...])
if !remaining.isEmpty {
// Seed for the reuse path is sampled at the end of this decodePrompt; apply
// the word-continuation constraint to it just like the fresh path does.
engine.setForceWordContinuation(autocompleteSequenceID, options.forceWordContinuation)
var mutableRemaining = remaining
let status = engine.decodePrompt(
autocompleteSequenceID,
Expand Down Expand Up @@ -423,6 +445,10 @@ nonisolated final class LlamaRuntimeCore: @unchecked Sendable {
throw LlamaRuntimeError.generationFailed("Unable to create inference sequence.")
}

// The engine samples the first (seed) token at the end of decodePrompt, so set the
// word-continuation constraint here, before decoding.
engine.setForceWordContinuation(seqID, options.forceWordContinuation)

var tokens = promptTokens
let status = engine.decodePrompt(seqID, &tokens, Int32(tokens.count), 0)
guard status == .ok else {
Expand Down Expand Up @@ -460,7 +486,8 @@ nonisolated final class LlamaRuntimeCore: @unchecked Sendable {
top_p: Float(options.topP),
min_p: Float(options.minP),
repetition_penalty: Float(options.repetitionPenalty),
seed: options.seed ?? 0
seed: options.seed ?? 0,
single_line: options.singleLine
)
}

Expand Down
7 changes: 6 additions & 1 deletion Cotabby/Services/Runtime/LlamaSuggestionEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ final class LlamaSuggestionEngine {
topP: request.topP,
minP: request.minP,
repetitionPenalty: request.repetitionPenalty,
seed: request.randomSeed
seed: request.randomSeed,
singleLine: !request.isMultiLineEnabled,
forceWordContinuation: MidWordContinuationPolicy.shouldForceContinuation(
precedingText: request.context.precedingText,
trailingText: request.context.trailingText
)
)
)
try Task.checkCancellation()
Expand Down
Loading