AI Secretary

AI Secretary — Support

What this app is

AI Secretary is a native chat client for iPhone and iPad that connects to your own AI backend. It’s pure SwiftUI with no third-party dependencies, and it uses a real three-column layout on iPad.

What it does: streaming replies; Markdown with code blocks and tables; Mermaid diagrams (rendered by a bundled engine, so they work with no internet at all); conversation history; document and image attachments; export to Word / PowerPoint / Markdown / plain text; voice input and read-aloud; and multiple saved backends you can switch between.

⚠️ Read this first: you must bring your own backend

This app ships with no AI service. A fresh install is empty — no default server, no bundled key. Until you give it a working backend address and key, it cannot connect to anything and will sit on “no backend bound”.

Four backend kinds are supported:

Kind What it is Example address Key
Hermes Agent A self-hosted agent gateway; keeps sessions server-side, supports tool calls and approvals http://100.x.y.z:8642 API_SERVER_KEY
OpenAI-compatible OpenAI itself, or any /v1/chat/completions compatible endpoint https://api.openai.com sk-…
Claude API Anthropic Messages API https://api.anthropic.com sk-ant-…
LangServe A LangChain LangServe /stream endpoint https://your-chain.example.com May be left empty

Claude requires a paid API key. Claude subscription (Pro / Max) sign-in credentials do not work against the API — they will only produce a 401.

Which backend you use, how you obtain a key, and what it costs are between you and that provider (or your own server). The app takes no part in it.

Getting started: three ways to bind a backend

Any of the three works. All of them show a confirmation screen naming the destination before anything is saved — deliberately, because binding decides where everything you type next gets sent.

1. Scan a QR code (fastest)

  1. Open the app, tap ☰ in the top-left ▸ Connection Settings (or, when nothing is bound yet, the “Bind now” button in the middle of the screen);
  2. Tap Scan QR to bind;
  3. Put the code in the frame — the device vibrates on a successful scan;
  4. Check the name and address on the confirmation screen, then confirm.

Where does the QR code come from? If you already have a device bound, open its Connection Settings, swipe right on that connection, and choose Generate QR code. Scan it with the new device. ⚠️ That code contains your API key. Don’t screenshot it and send it to anyone.

The same binding payload also travels as a link. Two ways to use it:

  • Open the link directly — the app launches and shows the confirmation screen;
  • Or go to Connection Settings ▸ Scan QR to bind and paste aisecretary://… into the text field at the bottom, then tap Bind.

That same field also accepts a bare JSON object ({"name":…,"kind":…,"url":…,"key":…}), for codes produced by generic tools.

On a device with no camera (the Simulator, for instance) this path and “pick a QR image from Photos” are shown automatically.

3. Enter it by hand

  1. Connection Settings ▸ Add manually, then pick the backend kind;
  2. Fill in:
    • Name — anything; it’s only a label in the list;
    • Address — see the table above. You can omit the scheme: Hermes defaults to http://, the other three default to https://. Trailing slashes are stripped automatically;
    • Key — stored in the iOS Keychain, not in ordinary settings;
    • Model — needed only for OpenAI-compatible and Claude (the Hermes gateway decides its own; LangServe doesn’t use one).
  3. Tap Save.

Once bound, tapping any host in the Host status section of Connection Settings tests that one host on its own — reachability, gateway version, and the model actually running — without switching your active connection.

Troubleshooting

Can’t connect / always shows offline

In order:

  1. Tap the host in Connection Settings ▸ Host status to test just that one and read the actual error it returns.
  2. Is the address right? Did you include the port (Hermes defaults to 8642)? Remember the scheme defaults: Hermes fills in http://, OpenAI / Claude / LangServe fill in https://. If your Hermes is actually behind HTTPS, you must write https:// explicitly.
  3. Getting 404? The host is reachable but the path is wrong. Enter host and port only — don’t append /v1/chat/completions to the address field.
  4. Is the backend actually running? Try the same address from a browser or curl on a computer on the same network.
  5. Can the phone reach that machine at all? See “backend on a private network” below.

401 (authentication failed)

  • Wrong or expired key. Swipe the connection in Connection Settings ▸ Edit and paste the key again — watch for leading/trailing whitespace or a newline, which copying from a chat app frequently adds.
  • Using Claude subscription credentials. The Claude API accepts only a paid API key starting with sk-ant-; subscription sign-in credentials do not apply here.
  • After a reinstall or a device change: keys live in the Keychain and do not travel with the connection list. If a connection is flagged as missing its key, scan the code again or re-enter the key by hand.
  • Hermes: confirm the API_SERVER_KEY in the server’s .env matches what you entered, and restart the gateway after changing it.

Backend on a private network / VPN / Tailscale

The app sends requests; it does not build the network path for you. If your backend is at 100.x.x.x (Tailscale), 192.168.x.x, or another private address:

  • Make sure the iPhone itself is on that network — the Tailscale / WireGuard client must be installed on the phone and connected. If the VPN is down, the app cannot connect, and that isn’t an app problem.
  • On cellular, only an active VPN gets you to a private address. Being on some Wi-Fi is not enough — someone else’s Wi-Fi will not reach the 192.168.1.x box in your house.
  • For a local address on the same Wi-Fi, iOS gates local network access: check Settings ▸ Privacy & Security ▸ Local Network and make sure AI Secretary is enabled.
  • Check what the server binds to. A backend listening only on 127.0.0.1 is unreachable from any other device; it needs to listen on a private-network address (its Tailscale address, for example). Don’t take the shortcut of binding 0.0.0.0 — especially for an agent gateway that can run commands, which would expose it to the whole LAN.
  • Plain HTTP is permitted precisely for this scenario, so “iOS blocked it because it wasn’t HTTPS” will not be your failure mode.

Voice input isn’t working

  • Two permissions are needed on first use: microphone and speech recognition. Missing either one stops it. If you previously declined, re-enable them in Settings ▸ AI Secretary.
  • “Speech recognition is unavailable”: try a different system language, or check your network — when a language can’t be recognized on-device on your hardware, iOS needs a connection to do it.
  • Talking while a reply streams in: dictation stops automatically during streaming. Wait for the turn to finish, then tap the microphone again.
  • Wrong recognition language: the recognizer follows your system locale first, then Chinese. Change the system language to change it.

Read-aloud sounds bad, or doesn’t speak

  • Robotic voice: iOS ships the lowest-quality synthetic voice by default. Download the Enhanced or Premium voice for your language in Settings ▸ Accessibility ▸ Spoken Content ▸ Voices — the app automatically picks the best-quality voice installed. They’re free; they’re just not installed by default.
  • Note that Siri’s voices are reserved to the system and can’t be used by apps, so downloading only Siri voices changes nothing.
  • Speech rate is under ☰ ▸ Preferences ▸ Input & read-aloud.
  • Code blocks are skipped when reading aloud — an entire code listing read out is unlistenable.

iPad layout looks wrong

  • All three columns (agents / conversations / chat) appear only when the window is wide enough — roughly 1100pt and up, i.e. a large iPad in full-screen landscape. In a narrower window the sidebar hides behind the toggle in the top-left.
  • In Stage Manager or Split View, a narrowed window drops to two columns or one. That’s the intended adaptive behaviour; widen the window and the columns come back.
  • All four orientations are supported. If it won’t rotate, check the system rotation lock in Control Center first.

Other

  • A conversation disappeared: Hermes-style backends keep sessions on the server, so they follow you across devices. Claude / OpenAI / LangServe are stateless — that history lives only on this device and does not survive a reinstall or a device change.
  • Images missing from an old conversation: the server keeps no images; only the local copy exists, and the local cache evicts the oldest images past 500 MB.
  • An attachment got truncated: raise the attachment character limit under ☰ ▸ Preferences ▸ Documents. Anything past the limit is not sent, and the prompt says so.
  • Where exported files go: ☰ ▸ Files shows the inbox and exports folders. They’re also reachable directly from the system Files app.

Contact

Anything the above doesn’t solve, plus bug reports and suggestions:

jackdark425@qq.com

Bug reports go much faster with: device model and iOS version, backend kind (Hermes / OpenAI / Claude / LangServe), and the full error text shown on screen. Please do not send your API key or your binding QR code. ```


AI 秘书 · 支持

这是什么

AI 秘书是一个 iPhone / iPad 上的原生聊天客户端,用来连接你自己的 AI 后端。 它是纯原生 SwiftUI 写的,没有第三方依赖,iPad 上是真正的三栏布局。

它能做的:流式回复、Markdown(含代码块和表格)、Mermaid 图表(渲染引擎随包内置, 断网也能画)、对话历史、文档与图片附件、导出成 Word / PowerPoint / Markdown / 纯文本、 语音输入与朗读、同时保存多个后端连接随时切换。

⚠️ 先看这个:你需要自备后端

这个 App 不附带任何 AI 服务。 装好之后它是空的——没有默认服务器,也没有内置密钥。 在你给它一个能用的后端地址和密钥之前,它连不上任何东西,会一直停在「还没有绑定后端」。

支持四种后端:

类型 说明 地址示例 密钥
Hermes Agent 自建 agent 网关,服务端保存会话,支持工具调用与批准 http://100.x.y.z:8642 API_SERVER_KEY
OpenAI 兼容 OpenAI 官方,或任何 /v1/chat/completions 兼容端点 https://api.openai.com sk-…
Claude API Anthropic Messages API https://api.anthropic.com sk-ant-…
LangServe LangChain LangServe 的 /stream 端点 https://your-chain.example.com 可留空

Claude 只认付费 API key。 Claude 订阅(Pro / Max)的登录凭证在 API 上不适用, 填进去只会得到 401。

选哪个后端、密钥怎么来、费用怎么算,都是你和那家服务商(或你自己那台服务器)之间的事, 这个 App 不参与。

快速上手:三种绑定方式

三种方式都能把一个后端绑进来。不管哪一种,都会先弹一个确认页告诉你要绑到哪台机器, 你点同意才真正生效——这是故意的,绑定意味着之后你打的每一个字都会发到那里。

方式一:扫二维码(最快)

  1. 打开 App,点左上角 ☰ ▸ 连接设置(没绑定时也可以直接点屏幕中间的「去绑定」);
  2. 扫码绑定
  3. 把二维码放进取景框,扫到会震一下;
  4. 在确认页上核对名称和地址,点同意。

这个二维码从哪来? 如果你已经在另一台设备上绑好了,在那台设备的「连接设置」里 右滑那条连接 → 生成二维码,用新设备扫它即可。 ⚠️ 这张码里含密钥,别截图外发。

方式二:粘贴 aisecretary:// 链接

绑定信息也可以是一条链接。两种用法:

  • 直接点开这条链接,App 会打开并弹出确认页;
  • 或者进 连接设置 ▸ 扫码绑定,在下方的输入框里粘贴 aisecretary://…,点「绑定」。

同一个输入框也接受一段裸 JSON({"name":…,"kind":…,"url":…,"key":…}),方便用通用 工具生成的码。

没有摄像头的设备(比如模拟器)会自动显示这一路以及「从相册选择二维码」。

方式三:手动填

  1. 连接设置 ▸ 手动添加,从菜单里选后端类型;
  2. 填:
    • 名称 — 随便起,只是列表里显示用;
    • 地址 — 见上表。不带 http:// / https:// 也行:Hermes 会补成 http://, 其他三种会补成 https://;结尾多余的 / 会自动去掉;
    • 密钥 — 保存进 iOS 钥匙串,不进普通配置文件;
    • 模型 — 只有 OpenAI 兼容和 Claude 需要填(Hermes 由网关决定,LangServe 不需要)。
  3. 点「保存」。

绑好之后,在「连接设置」的主机状态一栏点任意一台主机,可以单独测它是否可达、 版本多少、实际在跑什么模型——不会切换你当前的连接

常见问题排查

连不上 / 一直显示离线

按顺序排查:

  1. 进「连接设置 ▸ 主机状态」点一下那台主机,让它单独测一次,看返回的具体错误。
  2. 地址对不对? 端口有没有带上(Hermes 默认 8642)?记住补全规则:Hermes 补 http://,OpenAI / Claude / LangServe 补 https://。如果你的 Hermes 其实是 HTTPS, 必须显式写 https://
  3. 404 说明主机通了但路径不对——检查地址是不是多带或少带了路径部分。 地址栏只填到主机和端口,别把 /v1/chat/completions 也填进去。
  4. 后端真的在跑吗? 用同一网络下的电脑浏览器或 curl 访问同一个地址试试。
  5. 手机是不是根本到不了那台机器? 见下面「后端在内网 / VPN 里」。

报 401(认证失败)

  • 密钥填错或过期。进「连接设置」左滑该连接 → 编辑,重新粘贴密钥(注意首尾空格 和换行,从聊天软件里复制常常会多带一个)。
  • 用了 Claude 订阅凭证。Claude API 只认 sk-ant- 开头的付费 API key,订阅账号的 登录凭证在这里不适用。
  • 重装或换设备之后:密钥在钥匙串里,不随连接列表走。如果某条连接显示「缺少密钥」, 重新扫一次码或手动补一次密钥即可。
  • Hermes:确认服务端 .env 里的 API_SERVER_KEY 和你填的是同一个,改完记得重启网关。

后端在内网 / VPN / Tailscale 里

App 只管发请求,不负责替你把网络打通。如果后端是 100.x.x.x(Tailscale)、 192.168.x.x 或其他私有地址:

  • 确认 iPhone 本身在那个网络里:Tailscale / WireGuard 这类客户端要在手机上装好并 处于连接状态;VPN 断了 App 就一定连不上,这不是 App 的问题。
  • 用蜂窝网络时要格外注意:只有 VPN 在跑,手机才能到内网地址;单纯连着 Wi-Fi 但那是别人家的 Wi-Fi,一样到不了你家里的 192.168.1.x
  • 同一 Wi-Fi 下的本地地址:iOS 会对访问本地网络做限制,请到 「设置 ▸ 隐私与安全性 ▸ 本地网络」里确认 AI 秘书是开着的。
  • 服务端绑的地址:如果后端只监听 127.0.0.1,外部设备一律连不上;需要它监听在 内网地址(比如那台机器的 Tailscale 地址)上。注意别为了图省事绑 0.0.0.0——尤其是 能执行命令的 agent 网关,那等于把它敞给整个局域网。
  • App 允许明文 HTTP 正是为这种场景准备的,所以「因为是 http 所以被 iOS 拦了」不会是 你的失败原因。

语音输入不工作

  • 第一次用要授权两项:麦克风语音识别,少一项都不行。被拒过的话,去 「设置 ▸ AI 秘书」里重新打开。
  • 提示「语音识别当前不可用」:换一下系统语言对应的识别语言,或检查网络——某些语言 在你的设备上不支持本机识别时,iOS 需要联网才能识别。
  • 说话时正好在出字:正在流式接收回复时会自动停止听写,等这一轮回完再按麦克风。
  • 识别语言不对:识别器优先跟随你的系统语言,其次是中文。改系统语言即可。

朗读的声音很难听 / 不出声

  • 声音太机械:iOS 默认给的是最低品质的合成音。到 「设置 ▸ 辅助功能 ▸ 朗读内容 ▸ 声音」里下载对应语言的增强版高级版语音, App 会自动挑设备上品质最好的那个。这是免费的,只是默认不装。
  • 注意 Siri 的声音是系统专用的,App 不能用,所以只下载 Siri 语音没有效果。
  • 语速在「☰ ▸ 偏好设置 ▸ 输入与朗读」里调。
  • 朗读会跳过代码块——整段代码念出来没法听。

iPad 上布局不对

  • 三栏(助手 / 会话 / 对话)只在窗口足够宽时同时显示,大约需要 1100pt 以上, 也就是全屏横屏的大尺寸 iPad。窗口窄一些时侧栏会自动收起,点左上角的按钮可以拉出来。
  • 用台前调度或分屏时,App 窗口被压窄,会自动退成两栏甚至单栏——这是正常的自适应, 把窗口拉宽就回来了。
  • 四个方向都支持。如果不跟着转,先检查是不是开了系统的方向锁定(控制中心里那个锁)。

其他

  • 对话找不到了:Hermes 这类后端的会话存在服务端,换设备也能看到;Claude / OpenAI / LangServe 是无状态的,历史只存在这台设备本机——换设备或卸载重装就没有了。
  • 图片翻旧对话时不见了:服务端不保存图片,只有本机留了一份,缓存超过 500 MB 会从 最旧的开始删。
  • 附件太长被截断:在「☰ ▸ 偏好设置 ▸ 文档」里调「附件字数上限」。超出的部分不会 发送,并会在提示词里说明已截断。
  • 导出的文件在哪:「☰ ▸ 文件」里能看到「收件」和「导出」两个目录;系统「文件」App 里也能直接找到它们。

联系我们

上面没解决的问题,或者要报 bug、提建议:

jackdark425@qq.com

报 bug 时如果能附上这些信息会快很多:设备型号与 iOS 版本、后端类型(Hermes / OpenAI / Claude / LangServe)、界面上显示的完整错误文字。请不要把你的 API 密钥或绑定二维码 发过来。 ```