@intentcomputing/koko-agent-sdk 1.0.1 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +13 -6
  3. package/README.zh-CN.md +13 -4
  4. package/docs/BACKEND_AUTH_DEMOS.md +42 -0
  5. package/docs/BACKEND_AUTH_DEMOS.zh-CN.md +191 -0
  6. package/docs/CONFIGURATION.md +188 -0
  7. package/docs/CONFIGURATION.zh-CN.md +195 -0
  8. package/docs/INTEGRATION.md +15 -6
  9. package/docs/INTEGRATION.zh-CN.md +13 -4
  10. package/lib/commonjs/KokoAgent.js +13 -11
  11. package/lib/commonjs/KokoAgent.js.map +1 -1
  12. package/lib/commonjs/client/AgentSession.js +3 -1
  13. package/lib/commonjs/client/AgentSession.js.map +1 -1
  14. package/lib/commonjs/client/GatewayClient.js +66 -12
  15. package/lib/commonjs/client/GatewayClient.js.map +1 -1
  16. package/lib/commonjs/cursor/CursorOverlay.js +1 -2
  17. package/lib/commonjs/cursor/CursorOverlay.js.map +1 -1
  18. package/lib/commonjs/index.js.map +1 -1
  19. package/lib/commonjs/provider/KokoProvider.js +1 -2
  20. package/lib/commonjs/provider/KokoProvider.js.map +1 -1
  21. package/lib/commonjs/provider/KokoUiContext.js +5 -7
  22. package/lib/commonjs/provider/KokoUiContext.js.map +1 -1
  23. package/lib/commonjs/ui/KokoChatSheet.js +1 -2
  24. package/lib/commonjs/ui/KokoChatSheet.js.map +1 -1
  25. package/lib/commonjs/ui/KokoComposer.js +1 -2
  26. package/lib/commonjs/ui/KokoComposer.js.map +1 -1
  27. package/lib/commonjs/ui/KokoDialogHost.js +1 -2
  28. package/lib/commonjs/ui/KokoDialogHost.js.map +1 -1
  29. package/lib/commonjs/ui/KokoObserver.js +1 -2
  30. package/lib/commonjs/ui/KokoObserver.js.map +1 -1
  31. package/lib/commonjs/ui/KokoSubtitle.js +1 -2
  32. package/lib/commonjs/ui/KokoSubtitle.js.map +1 -1
  33. package/lib/commonjs/ui/KokoTaskPanel.js +1 -2
  34. package/lib/commonjs/ui/KokoTaskPanel.js.map +1 -1
  35. package/lib/module/KokoAgent.js +12 -9
  36. package/lib/module/KokoAgent.js.map +1 -1
  37. package/lib/module/client/AgentSession.js +3 -1
  38. package/lib/module/client/AgentSession.js.map +1 -1
  39. package/lib/module/client/GatewayClient.js +66 -12
  40. package/lib/module/client/GatewayClient.js.map +1 -1
  41. package/lib/module/index.js.map +1 -1
  42. package/lib/module/provider/KokoUiContext.js +4 -5
  43. package/lib/module/provider/KokoUiContext.js.map +1 -1
  44. package/lib/typescript/commonjs/KokoAgent.d.ts.map +1 -1
  45. package/lib/typescript/commonjs/client/AgentSession.d.ts.map +1 -1
  46. package/lib/typescript/commonjs/client/GatewayClient.d.ts +24 -2
  47. package/lib/typescript/commonjs/client/GatewayClient.d.ts.map +1 -1
  48. package/lib/typescript/commonjs/index.d.ts +1 -1
  49. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  50. package/lib/typescript/commonjs/provider/KokoUiContext.d.ts.map +1 -1
  51. package/lib/typescript/commonjs/types.d.ts +7 -2
  52. package/lib/typescript/commonjs/types.d.ts.map +1 -1
  53. package/lib/typescript/module/KokoAgent.d.ts.map +1 -1
  54. package/lib/typescript/module/client/AgentSession.d.ts.map +1 -1
  55. package/lib/typescript/module/client/GatewayClient.d.ts +24 -2
  56. package/lib/typescript/module/client/GatewayClient.d.ts.map +1 -1
  57. package/lib/typescript/module/index.d.ts +1 -1
  58. package/lib/typescript/module/index.d.ts.map +1 -1
  59. package/lib/typescript/module/provider/KokoUiContext.d.ts.map +1 -1
  60. package/lib/typescript/module/types.d.ts +7 -2
  61. package/lib/typescript/module/types.d.ts.map +1 -1
  62. package/package.json +5 -1
  63. package/src/KokoAgent.ts +12 -9
  64. package/src/client/AgentSession.ts +2 -0
  65. package/src/client/GatewayClient.ts +88 -14
  66. package/src/index.ts +2 -0
  67. package/src/provider/KokoUiContext.tsx +4 -5
  68. package/src/types.ts +7 -2
@@ -0,0 +1,195 @@
1
+ # SDK 完整配置参考
2
+
3
+ > English: [CONFIGURATION.md](./CONFIGURATION.md)
4
+
5
+ 本文覆盖宿主接入时可配置的公开接口:`KokoProvider`、`KokoAgentConfig`、运行时外观、单次任务参数,以及内置 UI 组件。TypeScript 类型定义仍是最终准源。
6
+
7
+ ## 完整示例
8
+
9
+ ```tsx
10
+ import React from 'react';
11
+ import {
12
+ KokoProvider,
13
+ openKokoChat,
14
+ setKokoAppearance,
15
+ } from '@intentcomputing/koko-agent-sdk';
16
+
17
+ export function App() {
18
+ const tokenProvider = React.useCallback(async () => {
19
+ const response = await hostApi.get('/koko/access-token');
20
+ return response.data as { accessToken: string; expiresAt: number };
21
+ }, []);
22
+
23
+ return (
24
+ <KokoProvider
25
+ cursor
26
+ observer
27
+ dialogs
28
+ resumeAfterReload
29
+ config={{
30
+ gateway: {
31
+ baseUrl: 'https://sdk.intentcomputing.cn',
32
+ tokenProvider,
33
+ // appId 通常无需填写,默认读取 Bundle ID / Package Name。
34
+ },
35
+ locale: 'zh',
36
+ theme: 'light', // 填宿主主题;Koko 浮层会使用对比主题。
37
+ branding: {
38
+ name: 'My Assistant',
39
+ tagline: '帮你操作当前 App',
40
+ placeholder: '告诉我你想做什么…',
41
+ primaryColor: '#6D4AFF',
42
+ icon: require('./assistant.png'),
43
+ },
44
+ confirmation: {
45
+ requireUserConfirm: true,
46
+ mode: 'preflight',
47
+ },
48
+ webWalletAliases: ['My Wallet'],
49
+ dumpMaxDepth: 80,
50
+ dumpSkipInvisible: true,
51
+ cursorDurationMs: 480,
52
+ observer: true,
53
+ debug: false,
54
+ onUsageEvent: event => analytics.track('koko_usage', event),
55
+ }}
56
+ >
57
+ <HostNavigation />
58
+ </KokoProvider>
59
+ );
60
+ }
61
+ ```
62
+
63
+ ## `KokoProvider` props
64
+
65
+ | 配置 | 类型 | 默认值 | 说明 |
66
+ |---|---|---:|---|
67
+ | `children` | `ReactNode` | 必填 | 宿主应用或最外层导航树。 |
68
+ | `config` | `KokoAgentConfig` | `{}` | Agent、网关、品牌和确认策略,详见下表。 |
69
+ | `cursor` | `boolean` | `true` | 显示可观测操作光标。 |
70
+ | `observer` | `boolean` | 继承 `config.observer` | 显示任务进度条和对话面板宿主;显式传入时优先。 |
71
+ | `dialogs` | `boolean` | `true` | 挂载 SDK 内置确认和追问弹窗。关闭后,宿主应提供对应回调。 |
72
+ | `resumeAfterReload` | `boolean` | `true` | JS 上下文因语言、主题或宿主重载而中断时,最多恢复一次最近任务。 |
73
+ | `remoteSmokePort` | `number` | `0` | 仅供开发联调的本机 smoke 驱动端口;生产包不要配置。 |
74
+ | `composerPlaceholder` | `string` | — | 已废弃;改用 `config.branding.placeholder`。 |
75
+
76
+ `KokoProvider.observer={false}` 只隐藏内置进度/对话 UI;`config.observer={false}` 还会关闭自动任务日志。两者都为 `true` 时功能完整。
77
+
78
+ ## `KokoAgentConfig`
79
+
80
+ | 配置 | 类型 | 默认值 | 说明 |
81
+ |---|---|---:|---|
82
+ | `gateway` | `GatewayConfig` | — | 正式运行必需的网关和短 Token 配置。 |
83
+ | `locale` | `'zh' \| 'en'` | `'en'` | SDK 内置 UI 初始语言。运行时变化优先使用 `setKokoAppearance`。 |
84
+ | `theme` | `'light' \| 'dark'` | `'light'` | **宿主 App 当前主题**;Koko 浮层会使用相反主题以保持可见。 |
85
+ | `branding` | `KokoBrandingConfig` | Koko 默认品牌 | 自定义名称、图标、文案和主色;需要 `custom_branding` 权益。 |
86
+ | `confirmation` | `ConfirmationPolicy` | 需要确认、`preflight` | 高风险任务的人工确认策略。 |
87
+ | `onConfirmSensitive` | `(ctx) => Promise<boolean>` | 内置确认弹窗 | 自定义敏感操作确认。返回 `true` 才继续。 |
88
+ | `webWalletAliases` | `string[]` | `[]` | 宿主确认属于自身注入钱包的公开钱包名称。只声明已验证别名。 |
89
+ | `dumpMaxDepth` | `number` | `80` | 原生可访问性树最大读取深度;过小会截断 RN 导航/组件库下的页面正文。 |
90
+ | `dumpSkipInvisible` | `boolean` | `true` | 读取页面时丢弃不可见节点。 |
91
+ | `cursorDurationMs` | `number` | `480` | 默认光标移动动画时长,单位毫秒。 |
92
+ | `observer` | `boolean` | `true` | 启用任务日志;Provider 未显式设置 `observer` 时也控制内置进度/对话 UI。 |
93
+ | `debug` | `boolean` | Metro Debug 为 `true`;Release 为 `false` | 输出能力和执行步骤日志,不放宽安全策略。正式包建议显式设为 `false`。 |
94
+ | `devMode` | `boolean` | 同 `debug` | 已废弃的 `debug` 别名。 |
95
+ | `onUsageEvent` | `(event) => void` | — | 本地分析/UX 事件旁路通知,不参与计费,也不能阻塞任务。 |
96
+
97
+ ### `gateway`
98
+
99
+ | 配置 | 类型 | 默认值 | 说明 |
100
+ |---|---|---:|---|
101
+ | `baseUrl` | `string` | `https://sdk.intentcomputing.net` | 海外/OpenAI 网关;国内/DeepSeek 使用 `https://sdk.intentcomputing.cn`。正式构建只接受官方地址。 |
102
+ | `tokenProvider` | `() => Promise<string \| { accessToken; expiresAt? }>` | — | 推荐。向**宿主后端**获取短期 Token。SDK 仅在内存中缓存,在请求时发现临近过期才刷新,401 后强制刷新并重试一次。 |
103
+ | `token` | `string` | — | 旧版静态 Token,仅用于本地开发和迁移;不要放进正式包。 |
104
+ | `appId` | `string` | 原生 Bundle ID / Package Name | 必须与服务端登记的宿主应用一致;通常无需手填。 |
105
+
106
+ `tokenProvider` 返回对象时,`expiresAt` 使用 Unix **毫秒**。若省略,SDK 尝试读取 JWT `exp`;两者都没有时按 60 秒处理。`clientSecret`、DeepSeek/OpenAI Key 永远不得进入 App。
107
+
108
+ ### `branding`
109
+
110
+ | 配置 | 类型 | 默认值 | 说明 |
111
+ |---|---|---:|---|
112
+ | `name` | `string` | `Koko` | 助手显示名称。 |
113
+ | `icon` | `number \| { uri: string } \| string` | 默认 K 标记 | 支持 `require()`、图片 URI/Data URI 或短文字标记。 |
114
+ | `tagline` | `string` | 本地化默认文案 | 对话页副标题。 |
115
+ | `placeholder` | `string` | 本地化默认文案 | 输入框占位文案。 |
116
+ | `primaryColor` | `string` | SDK 默认主色 | Badge、发送按钮等强调色。使用 React Native 可识别的颜色字符串。 |
117
+
118
+ 没有品牌权益时,SDK 自动降级到 Koko 默认品牌,并通过 `onUsageEvent` 发出一次 `branding_downgraded`。
119
+
120
+ ### `confirmation`
121
+
122
+ | 配置 | 类型 | 默认值 | 说明 |
123
+ |---|---|---:|---|
124
+ | `requireUserConfirm` | `boolean` | `true` | 是否要求高风险目标由用户确认。 |
125
+ | `mode` | `'preflight' \| 'inline' \| 'off'` | `'preflight'` | `preflight` 在任务开始前确认一次;`inline` 为兼容旧版的逐步确认;`off` 关闭 SDK 确认。 |
126
+ | `sensitivePatterns` | `RegExp[]` | SDK 内置规则 | 自定义高风险目标匹配规则。传入非空数组时替换内置规则。 |
127
+
128
+ 关闭 SDK 确认不会绕过密码、助记词、私钥、OTP 等隐私页面的本地门禁;这些内容仍必须由用户亲自操作。
129
+
130
+ ### `onUsageEvent` 事件
131
+
132
+ 可能收到:`task_started`、`task_finished`、`agent_step`、`quota_exceeded`、`sheet_opened`、`sheet_closed`、`branding_downgraded`。不得把事件里的任务文本继续发送到未经授权的分析服务。
133
+
134
+ ## 运行时语言和主题
135
+
136
+ ```tsx
137
+ import { setKokoAppearance } from '@intentcomputing/koko-agent-sdk';
138
+
139
+ useEffect(() => {
140
+ setKokoAppearance({ locale: hostLocale, theme: hostTheme });
141
+ }, [hostLocale, hostTheme]);
142
+ ```
143
+
144
+ - `locale` 可传宿主语言字符串;以 `zh` 开头映射为中文,其余映射为英文。
145
+ - `theme` 填宿主真实主题:`'light'` 或 `'dark'`。
146
+ - 运行时外观优先级高于静态 `config.locale` / `config.theme`。
147
+
148
+ `getKokoAgent().configure(patch)` 可动态修改配置,但它执行浅合并;更新 `gateway`、`branding` 或 `confirmation` 时应传入完整子对象。语言/主题仍优先用 `setKokoAppearance`。
149
+
150
+ ## 单次任务覆盖项
151
+
152
+ ```tsx
153
+ await getKokoAgent().runGoal('打开设置', {
154
+ locale: 'zh-CN',
155
+ localRetries: 3,
156
+ userGateTimeoutMs: 300_000,
157
+ onAskUser: question => showHostQuestion(question),
158
+ onNarration: text => setHint(text),
159
+ });
160
+ ```
161
+
162
+ | 配置 | 默认值 | 说明 |
163
+ |---|---:|---|
164
+ | `baseUrl` / `tokenProvider` / `token` / `appId` | 继承 `config.gateway` | 仅覆盖本次任务的网关配置。 |
165
+ | `locale` | 当前有效语言 | 本次规划请求语言。 |
166
+ | `localRetries` | `3` | 只读 `dump/find` 的本地失败重试次数,范围 `0–3`;触摸、输入等写操作不会自动重放。 |
167
+ | `userGateTimeoutMs` | `300000` | 等待用户完成密码/助记词/授权等本地门禁的最长时间。 |
168
+ | `onAskUser` | 内置追问弹窗 | Agent 需要用户补充信息时的宿主回调。 |
169
+ | `onNarration` | — | 接收当前任务提示/旁白。 |
170
+
171
+ `resumedFromReload` 和 `resumes` 是 SDK 恢复机制内部字段,宿主不应主动设置。
172
+
173
+ ## 内置 UI 组件参数
174
+
175
+ | 组件 | 可配置项 |
176
+ |---|---|
177
+ | `KokoEntryButton` | `label`(默认 `Koko`)、`style`。生产宿主更推荐自绘入口并调用 `openKokoChat()`。 |
178
+ | `KokoComposer` | `placeholder`、`disabled`(默认 `false`)。 |
179
+ | `KokoObserver` | `cursor`(默认 `true`)、已废弃的 `composerPlaceholder`。通常由 Provider 自动挂载。 |
180
+ | `KokoOverlayLayer` | `style`、`pointerEvents`(默认 `box-none`)、`testID`。供自定义 SDK 浮层使用。 |
181
+
182
+ ## 低级操作参数
183
+
184
+ 这些 API 主要用于自定义集成;普通宿主不需要直接调用。
185
+
186
+ | 类型 | 可配置项及默认行为 |
187
+ |---|---|
188
+ | `DumpOptions` | `maxDepth`、`skipInvisible`、`silent`。未传时继承 Agent 配置。 |
189
+ | `TapOptions` | `revealIfNeeded`、`silent`、`cursorDurationMs`。任务规划器会自行决定何时滚动寻找目标。 |
190
+ | `SwipeOptions` | `durationMs`、`silent`。 |
191
+ | `PinchOptions` | `durationMs`(默认 `280`)、`silent`。 |
192
+ | `TypeOptions` | `clear`、`silent`。 |
193
+
194
+ 完整隐私边界见[隐私说明](PRIVACY.zh-CN.md),三端鉴权见[后端鉴权 Demo](BACKEND_AUTH_DEMOS.zh-CN.md)。
195
+
@@ -8,14 +8,14 @@ For React Native host apps. After installing the package you must link native co
8
8
 
9
9
  - React Native ≥ 0.73 (or Expo Dev Client / `expo prebuild` — **not Expo Go**)
10
10
  - iOS deployment target ≥ 15; ability to run `pod install`
11
- - An **app token** from Intent Computing (`gateway.token` — not a DeepSeek / OpenAI key)
11
+ - An Intent Computing console app with its one-time `clientId` and `clientSecret`; keep the secret on the host backend only
12
12
 
13
13
  ## Checklist
14
14
 
15
15
  1. Install the npm package
16
16
  2. iOS: `pod install` (Android usually autolinks)
17
17
  3. **Rebuild native** (Debug or Release)
18
- 4. Wrap the root tree with `KokoProvider` and set `token`
18
+ 4. Exchange credentials on the host backend and provide short-lived tokens to `KokoProvider`
19
19
  5. Launch and send a natural-language goal
20
20
 
21
21
  JS-only config changes can hot-reload via Metro. **First integration or any native SDK change requires a native rebuild.**
@@ -65,11 +65,15 @@ Wrap at the app root (or outermost navigation shell):
65
65
  import { KokoProvider } from '@intentcomputing/koko-agent-sdk';
66
66
 
67
67
  export default function App() {
68
+ const tokenProvider = React.useCallback(async () => {
69
+ const response = await hostApi.get('/koko/access-token');
70
+ return response.data as { accessToken: string; expiresAt: number };
71
+ }, []);
68
72
  return (
69
73
  <KokoProvider
70
74
  config={{
71
75
  gateway: {
72
- token: 'YOUR_APP_TOKEN',
76
+ tokenProvider,
73
77
  // Default: https://sdk.intentcomputing.net
74
78
  // China: https://sdk.intentcomputing.cn
75
79
  // baseUrl: 'https://sdk.intentcomputing.cn',
@@ -85,9 +89,11 @@ export default function App() {
85
89
  }
86
90
  ```
87
91
 
92
+ `tokenProvider` calls your backend, never Koko's exchange endpoint directly: the `clientSecret` must not enter the app. The SDK caches credentials using `expiresAt` or JWT `exp` and refreshes once after a 401. See the [backend demos](BACKEND_AUTH_DEMOS.md) for complete examples. Static `gateway.token` remains available only for local development and migration.
93
+
88
94
  `KokoProvider` will:
89
95
 
90
- - Initialize the agent with `gateway.token`
96
+ - Initialize the agent with `gateway.tokenProvider`
91
97
  - Mount cursor, progress, and chat sheet (optional — see below)
92
98
 
93
99
  Open chat from host UI:
@@ -101,6 +107,8 @@ getKokoAgent().openChat();
101
107
 
102
108
  ### Optional props / config
103
109
 
110
+ The table below is only the common subset. See the [complete configuration reference](CONFIGURATION.md) for every Provider, Agent, gateway, branding, runtime, per-run, and built-in component option.
111
+
104
112
  | Key | Purpose | Default |
105
113
  |--|--|--|
106
114
  | `cursor` | Action cursor overlay | `true` |
@@ -138,7 +146,7 @@ For custom private UIs, declare the gate before navigation or reveal and keep it
138
146
 
139
147
  1. Launch the app and use your host button wired to `openKokoChat()`. The provider does not create a host entry button.
140
148
  2. Send a verifiable goal; you should see dump → tap with a visible cursor.
141
- 3. Check that requests use the selected official gateway and a token bound to this app. Do not bundle an LLM API key. Validate privacy gates and outbound payloads using synthetic data.
149
+ 3. Check that requests use the selected official gateway and a short-lived token bound to this app. Do not bundle a client secret, long-lived token or LLM API key. Validate privacy gates and outbound payloads using synthetic data.
142
150
 
143
151
  ---
144
152
 
@@ -157,7 +165,7 @@ Not supported. Use a Dev Client, bare RN, or a production host binary.
157
165
  Use `portal:` / `file:`. If the package lives **outside** the monorepo, Metro may need `watchFolders` + `extraNodeModules` (usually unnecessary after npm publish).
158
166
 
159
167
  **Where does the token come from?**
160
- Intent Computing console / commercial onboarding — not a model-vendor API key.
168
+ Your backend exchanges its server-only Intent Computing client credentials for a short-lived token. It is not a model-vendor API key.
161
169
 
162
170
  ---
163
171
 
@@ -166,3 +174,4 @@ Intent Computing console / commercial onboarding — not a model-vendor API key.
166
174
  - Package overview: [../README.md](../README.md)
167
175
  - npm publish: [PUBLISH.md](./PUBLISH.md)
168
176
  - 中文接入指南: [INTEGRATION.zh-CN.md](./INTEGRATION.zh-CN.md)
177
+ - Backend authentication demos: [BACKEND_AUTH_DEMOS.md](./BACKEND_AUTH_DEMOS.md)
@@ -8,14 +8,14 @@
8
8
 
9
9
  - React Native ≥ 0.73(或 Expo Dev Client / `expo prebuild`,**不支持 Expo Go**)
10
10
  - iOS 部署目标 ≥ 15;需本机可 `pod install`
11
- - 从 Intent Computing 拿到 **应用 token**(`gateway.token`,不是 DeepSeek / OpenAI Key)
11
+ - 在 Intent Computing 用户后台创建应用并取得一次性显示的 `clientId` / `clientSecret`;`clientSecret` 只放宿主后端
12
12
 
13
13
  ## 步骤一览
14
14
 
15
15
  1. 安装 npm 包
16
16
  2. iOS `pod install`(Android 一般靠 autolinking)
17
17
  3. **重新编译原生**(Debug / Release 均可)
18
- 4. 根组件包一层 `KokoProvider` 并配置 token
18
+ 4. 宿主后端换取短期 token,App 用 `tokenProvider` 提供给 `KokoProvider`
19
19
  5. 将 `openKokoChat()` 对接宿主入口,再发自然语言任务
20
20
 
21
21
  之后若只改 JS 配置或升级包的纯 JS 部分,Metro 热更新即可;**SDK 含原生改动或首次接入,必须再编原生。**
@@ -63,11 +63,15 @@ npx react-native run-android
63
63
  import { KokoProvider } from '@intentcomputing/koko-agent-sdk';
64
64
 
65
65
  export default function App() {
66
+ const tokenProvider = React.useCallback(async () => {
67
+ const response = await hostApi.get('/koko/access-token');
68
+ return response.data as { accessToken: string; expiresAt: number };
69
+ }, []);
66
70
  return (
67
71
  <KokoProvider
68
72
  config={{
69
73
  gateway: {
70
- token: 'YOUR_APP_TOKEN',
74
+ tokenProvider,
71
75
  // 默认 https://sdk.intentcomputing.net(OpenAI)
72
76
  // 国内:https://sdk.intentcomputing.cn(DeepSeek)
73
77
  baseUrl: 'https://sdk.intentcomputing.cn',
@@ -82,6 +86,8 @@ export default function App() {
82
86
  }
83
87
  ```
84
88
 
89
+ `tokenProvider` 应调用宿主后端,不能直接调用 Koko 换 token 接口,因为 `clientSecret` 绝不能进入 App。SDK 会按 `expiresAt` 或 JWT `exp` 缓存凭证,并在 401 后刷新一次。宿主后端完整实现见[六种主流语言 Demo](BACKEND_AUTH_DEMOS.zh-CN.md)。`gateway.token` 仅保留给本地开发和迁移,不建议用于正式包。
90
+
85
91
  宿主也可主动打开会话:
86
92
 
87
93
  ```tsx
@@ -92,6 +98,8 @@ getKokoAgent().openChat();
92
98
 
93
99
  ### 可选开关
94
100
 
101
+ 下表仅列常用项。Provider、Agent、网关、品牌、运行时、单次任务及内置组件的所有选项见 [SDK 完整配置参考](CONFIGURATION.zh-CN.md)。
102
+
95
103
  | prop / config | 含义 | 默认 |
96
104
  |--|--|--|
97
105
  | `cursor` | 操作光标 | `true` |
@@ -113,7 +121,7 @@ getKokoAgent().openChat();
113
121
 
114
122
  1. 启动 App,通过接有 `openKokoChat()` 的宿主按钮打开助手;Provider 不会自动创建宿主入口。
115
123
  2. 输入可核验目标,应看到 dump → tap 与光标。
116
- 3. 请求打到官网网关(或 `baseUrl`),App 内无任何 LLM API Key。
124
+ 3. 请求打到官网网关(或 `baseUrl`),App 内无 `clientSecret`、长期 token 或任何 LLM API Key。
117
125
 
118
126
  ---
119
127
 
@@ -138,3 +146,4 @@ getKokoAgent().openChat();
138
146
  - 英文总览:[../README.md](../README.md)
139
147
  - 中文总览:[../README.zh-CN.md](../README.zh-CN.md)
140
148
  - 发布:[PUBLISH.zh-CN.md](./PUBLISH.zh-CN.md)
149
+ - 后端鉴权 Demo:[BACKEND_AUTH_DEMOS.zh-CN.md](./BACKEND_AUTH_DEMOS.zh-CN.md)
@@ -29,8 +29,7 @@ var _ExecutionGuard = require("./commercial/ExecutionGuard.js");
29
29
  var _AgentDebug = require("./commercial/AgentDebug.js");
30
30
  var _index = require("./i18n/index.js");
31
31
  var _ocrTarget = require("./assist/ocrTarget.js");
32
- var cache;
33
- function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var r, c, a = Object.defineProperty, n = { __proto__: null, default: e }; if (Object(e) !== e) return n; if (cache || "function" != typeof WeakMap || (cache = new WeakMap()), cache) { if (cache.has(e)) return cache.get(e); cache.set(e, n); } for (c in e) "default" !== c && {}.hasOwnProperty.call(e, c) && ((r = a && Object.getOwnPropertyDescriptor(e, c)) && (r.get || r.set) ? a(n, c, r) : n[c] = e[c]); return n; }
32
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
34
33
  /**
35
34
  * Koko Agent SDK runtime — dump / find / tap / swipe / pinch / type + cursor + confirm gate + task log.
36
35
  */
@@ -173,14 +172,18 @@ class KokoAgent {
173
172
  if (this.activeSession || this.claimingCheckpoint) {
174
173
  throw new Error((0, _index.runtimeText)('runtime.alreadyRunning', undefined, this.config?.locale));
175
174
  }
176
- const token = opts?.token ?? this.config.gateway?.token;
177
- if (!token) {
175
+ const gateway = {
176
+ token: opts?.token ?? this.config.gateway?.token,
177
+ tokenProvider: opts?.tokenProvider ?? this.config.gateway?.tokenProvider,
178
+ appId: opts?.appId ?? this.config.gateway?.appId
179
+ };
180
+ if (!gateway.token && !gateway.tokenProvider) {
178
181
  throw new Error(this.text('runtime.missingToken'));
179
182
  }
180
183
  const baseUrl = opts?.baseUrl ?? this.config.gateway?.baseUrl;
181
184
  const locale = (0, _index.gatewayLocale)((0, _index.currentLocale)(opts?.locale ?? this.config.locale));
182
185
  void _AccountStore.AccountStore.refresh({
183
- token,
186
+ ...gateway,
184
187
  baseUrl
185
188
  });
186
189
  const session = this.createSession({
@@ -191,7 +194,7 @@ class KokoAgent {
191
194
  onAskUser: opts?.onAskUser,
192
195
  onNarration: opts?.onNarration,
193
196
  baseUrl,
194
- token
197
+ ...gateway
195
198
  });
196
199
  this.activeSession = session;
197
200
  // An action can take down the context running it (locale/theme/RTL change,
@@ -206,7 +209,7 @@ class KokoAgent {
206
209
  await _RunCheckpoint.RunCheckpoint.clear().catch(() => {});
207
210
  if (this.activeSession === session) this.activeSession = null;
208
211
  void _AccountStore.AccountStore.refresh({
209
- token,
212
+ ...gateway,
210
213
  baseUrl
211
214
  });
212
215
  }
@@ -263,11 +266,10 @@ class KokoAgent {
263
266
 
264
267
  /** Refresh plan / quota / entitlements from gateway. */
265
268
  async refreshAccount() {
266
- const token = this.config.gateway?.token;
267
- if (!token) return null;
269
+ const gateway = this.config.gateway;
270
+ if (!gateway?.token && !gateway?.tokenProvider) return null;
268
271
  return _AccountStore.AccountStore.refresh({
269
- token,
270
- baseUrl: this.config.gateway?.baseUrl
272
+ ...gateway
271
273
  });
272
274
  }
273
275
  getAccount() {