mirror of
https://github.com/openclaw/openclaw.git
synced 2026-02-19 18:39:20 -05:00
feat(ios): add Talk voice directive hint toggle (#18250)
* feat(ios): add Talk voice directive hint toggle * docs(changelog): credit voice directive hint slice --------- Co-authored-by: Mariano Belinky <mariano@mb-server-643.local>
This commit is contained in:
@@ -7,6 +7,7 @@ Docs: https://docs.openclaw.ai
|
||||
### Changes
|
||||
|
||||
- Cron/Gateway: separate per-job webhook delivery (`delivery.mode = "webhook"`) from announce delivery, enforce valid HTTP(S) webhook URLs, and keep a temporary legacy `notify + cron.webhook` fallback for stored jobs. (#17901) Thanks @advaitpaliwal.
|
||||
- iOS/Talk: add a `Voice Directive Hint` toggle for Talk Mode prompts so users can disable ElevenLabs voice-switching instructions to save tokens when not needed. (#18250) Thanks @zeulewan.
|
||||
- Telegram/Agents: add inline button `style` support (`primary|success|danger`) across message tool schema, Telegram action parsing, send pipeline, and runtime prompt guidance. (#18241) Thanks @obviyus.
|
||||
|
||||
### Fixes
|
||||
|
||||
@@ -15,6 +15,7 @@ struct SettingsTab: View {
|
||||
@AppStorage("voiceWake.enabled") private var voiceWakeEnabled: Bool = false
|
||||
@AppStorage("talk.enabled") private var talkEnabled: Bool = false
|
||||
@AppStorage("talk.button.enabled") private var talkButtonEnabled: Bool = true
|
||||
@AppStorage("talk.voiceDirectiveHint.enabled") private var talkVoiceDirectiveHintEnabled: Bool = true
|
||||
@AppStorage("camera.enabled") private var cameraEnabled: Bool = true
|
||||
@AppStorage("location.enabledMode") private var locationEnabledModeRaw: String = OpenClawLocationMode.off.rawValue
|
||||
@AppStorage("location.preciseEnabled") private var locationPreciseEnabled: Bool = true
|
||||
@@ -255,6 +256,10 @@ struct SettingsTab: View {
|
||||
Text("Use this local override when gateway config redacts talk.apiKey for mobile clients.")
|
||||
.font(.footnote)
|
||||
.foregroundStyle(.secondary)
|
||||
Toggle("Voice Directive Hint", isOn: self.$talkVoiceDirectiveHintEnabled)
|
||||
Text("Include ElevenLabs voice switching instructions in the Talk Mode prompt. Disable to save tokens.")
|
||||
.font(.footnote)
|
||||
.foregroundStyle(.secondary)
|
||||
// Keep this separate so users can hide the side bubble without disabling Talk Mode.
|
||||
Toggle("Show Talk Button", isOn: self.$talkButtonEnabled)
|
||||
|
||||
|
||||
@@ -828,7 +828,11 @@ final class TalkModeManager: NSObject {
|
||||
private func buildPrompt(transcript: String) -> String {
|
||||
let interrupted = self.lastInterruptedAtSeconds
|
||||
self.lastInterruptedAtSeconds = nil
|
||||
return TalkPromptBuilder.build(transcript: transcript, interruptedAtSeconds: interrupted)
|
||||
let includeVoiceDirectiveHint = (UserDefaults.standard.object(forKey: "talk.voiceDirectiveHint.enabled") as? Bool) ?? true
|
||||
return TalkPromptBuilder.build(
|
||||
transcript: transcript,
|
||||
interruptedAtSeconds: interrupted,
|
||||
includeVoiceDirectiveHint: includeVoiceDirectiveHint)
|
||||
}
|
||||
|
||||
private enum ChatCompletionState: CustomStringConvertible {
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
public enum TalkPromptBuilder: Sendable {
|
||||
public static func build(transcript: String, interruptedAtSeconds: Double?) -> String {
|
||||
public static func build(
|
||||
transcript: String,
|
||||
interruptedAtSeconds: Double?,
|
||||
includeVoiceDirectiveHint: Bool = true
|
||||
) -> String {
|
||||
var lines: [String] = [
|
||||
"Talk Mode active. Reply in a concise, spoken tone.",
|
||||
"You may optionally prefix the response with JSON (first line) to set ElevenLabs voice (id or alias), e.g. {\"voice\":\"<id>\",\"once\":true}.",
|
||||
]
|
||||
|
||||
if includeVoiceDirectiveHint {
|
||||
lines.append(
|
||||
"You may optionally prefix the response with JSON (first line) to set ElevenLabs voice (id or alias), e.g. {\"voice\":\"<id>\",\"once\":true}."
|
||||
)
|
||||
}
|
||||
|
||||
if let interruptedAtSeconds {
|
||||
let formatted = String(format: "%.1f", interruptedAtSeconds)
|
||||
lines.append("Assistant speech interrupted at \(formatted)s.")
|
||||
|
||||
@@ -12,4 +12,18 @@ final class TalkPromptBuilderTests: XCTestCase {
|
||||
let prompt = TalkPromptBuilder.build(transcript: "Hi", interruptedAtSeconds: 1.234)
|
||||
XCTAssertTrue(prompt.contains("Assistant speech interrupted at 1.2s."))
|
||||
}
|
||||
|
||||
func testBuildIncludesVoiceDirectiveHintByDefault() {
|
||||
let prompt = TalkPromptBuilder.build(transcript: "Hello", interruptedAtSeconds: nil)
|
||||
XCTAssertTrue(prompt.contains("ElevenLabs voice"))
|
||||
}
|
||||
|
||||
func testBuildExcludesVoiceDirectiveHintWhenDisabled() {
|
||||
let prompt = TalkPromptBuilder.build(
|
||||
transcript: "Hello",
|
||||
interruptedAtSeconds: nil,
|
||||
includeVoiceDirectiveHint: false)
|
||||
XCTAssertFalse(prompt.contains("ElevenLabs voice"))
|
||||
XCTAssertTrue(prompt.contains("Talk Mode active."))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user