@guideai/react-native 0.1.0 → 0.2.0

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.
@@ -84,7 +84,7 @@ function describeToolCall(toolCall) {
84
84
  const ownScope = /\s+(me|self|current|mine)$/.test(noun);
85
85
  if (ownScope) noun = `your ${noun.replace(/\s+(me|self|current|mine)$/, "")}`;
86
86
  if (SELF_DESCRIBING.test(noun) || ownScope) return `${verb} ${noun}`;
87
- const singular = noun.replace(new RegExp("([a-z])(?<!s|u|i)s$"), "$1");
87
+ const singular = noun.replace(/([a-z])(?<!s|u|i)s$/, "$1");
88
88
  return `${verb} ${singular} information`;
89
89
  }
90
90
  function describeToolBatch(toolCalls) {
@@ -652,8 +652,11 @@ class ToolExecutor {
652
652
  }
653
653
  /** Read the user's auth token from the configured browser storage. */
654
654
  getAuthToken() {
655
+ var _a, _b;
655
656
  if (this.authConfig.type === "none") return null;
656
657
  try {
658
+ const supplied = this.authConfig.type === "bearer" ? (_b = (_a = this.credentials).authToken) == null ? void 0 : _b.call(_a) : null;
659
+ if (supplied) return supplied;
657
660
  let raw = null;
658
661
  const storageKey = this.authConfig.key;
659
662
  if (storageKey && this.authConfig.source) {
@@ -839,6 +842,7 @@ class ToolExecutor {
839
842
  });
840
843
  }
841
844
  _buildHeaders(toolCall) {
845
+ var _a;
842
846
  const headers = {
843
847
  "Content-Type": "application/json",
844
848
  Accept: "application/json"
@@ -885,6 +889,16 @@ class ToolExecutor {
885
889
  mergeHeader(name, value);
886
890
  }
887
891
  }
892
+ for (const declared of (_a = this.authConfig.app_headers) != null ? _a : []) {
893
+ if (!(declared == null ? void 0 : declared.name)) continue;
894
+ let value = null;
895
+ try {
896
+ value = this.credentials.read("app", declared.name);
897
+ } catch {
898
+ value = null;
899
+ }
900
+ mergeHeader(declared.name, value);
901
+ }
888
902
  return headers;
889
903
  }
890
904
  _resolveHeaderValue(value) {
@@ -1027,6 +1041,7 @@ const EP = {
1027
1041
  guidesRecord: () => _j([..._v, "guides", "record"]),
1028
1042
  events: () => _j([..._v, "events"]),
1029
1043
  chatAsk: () => _j([..._v, "chat", "ask"]),
1044
+ chatExecuteTool: () => _j([..._v, "chat", "execute-tool"]),
1030
1045
  onboardingCurrent: (userId) => `${_j([..._v, "onboarding", "current"])}?user_id=${encodeURIComponent(userId)}`,
1031
1046
  onboardingObserve: () => _j([..._v, "onboarding", "observe"]),
1032
1047
  onboardingDismiss: () => _j([..._v, "onboarding", "dismiss"]),
@@ -1084,6 +1099,9 @@ const MAX_CHAIN_ROUNDS = 5;
1084
1099
  const MAX_TOTAL_TOOL_CALLS = 10;
1085
1100
  const MAX_REPAIR_ROUNDS = 1;
1086
1101
  const REPAIRABLE_ERROR_TYPES = /* @__PURE__ */ new Set(["validation", "client", "not_found"]);
1102
+ function isServerTool(toolCall) {
1103
+ return (toolCall.method || "").toUpperCase() === "MCP";
1104
+ }
1087
1105
  class CopilotHarness {
1088
1106
  /**
1089
1107
  * @param tools How this platform actually touches the screen. Defaults to
@@ -1167,6 +1185,24 @@ class CopilotHarness {
1167
1185
  setToolContext(values) {
1168
1186
  this.toolContext = values && Object.keys(values).length > 0 ? values : void 0;
1169
1187
  }
1188
+ /**
1189
+ * The app's tool inputs as the API names them. A value declared in Copilot
1190
+ * Tools as filling other inputs (app key `course` fills `content_id`) is
1191
+ * sent under those names too; one the app set by that name already wins.
1192
+ */
1193
+ contextForTools() {
1194
+ var _a, _b, _c, _d;
1195
+ if (!this.toolContext) return void 0;
1196
+ const out = { ...this.toolContext };
1197
+ for (const input of (_c = (_b = (_a = this.activeTools) == null ? void 0 : _a.auth_config) == null ? void 0 : _b.app_inputs) != null ? _c : []) {
1198
+ const value = (input == null ? void 0 : input.key) ? this.toolContext[input.key] : void 0;
1199
+ if (value === void 0) continue;
1200
+ for (const name of (_d = input.fills) != null ? _d : []) {
1201
+ if (name && !(name in out)) out[name] = value;
1202
+ }
1203
+ }
1204
+ return out;
1205
+ }
1170
1206
  /** Whether copilot action tools are available for this site. */
1171
1207
  isEnabled() {
1172
1208
  return this.tools.definitions().length > 0 || this.activeTools !== null && this.activeTools.tools.length > 0;
@@ -1181,8 +1217,7 @@ class CopilotHarness {
1181
1217
  * 5. For non-tool queries, returns JSON response directly
1182
1218
  */
1183
1219
  async processMessage(question, pageUrl, pageSnapshot, chatMode, onStatus, onTextDelta, onToolCallEvent, abortSignal, userContext, onboardingUserId) {
1184
- var _a2, _b2, _c2;
1185
- var _a, _b, _c, _d, _e, _f, _g, _h;
1220
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j2, _k;
1186
1221
  const inputCheck = this.validator.validateUserInput(question);
1187
1222
  if (!inputCheck.valid) {
1188
1223
  return this._errorResponse(inputCheck.error || "Invalid input.");
@@ -1197,10 +1232,10 @@ class CopilotHarness {
1197
1232
  });
1198
1233
  const conversationHistory = this.memory.getRecentForLLM(10);
1199
1234
  const mayForwardToken = ((_b = (_a = this.activeTools) == null ? void 0 : _a.auth_config) == null ? void 0 : _b.forward_user_token) === true;
1200
- const userToken = mayForwardToken ? (_a2 = (_c = this.toolExecutor) == null ? void 0 : _c.getAuthToken()) != null ? _a2 : null : null;
1235
+ const userToken = mayForwardToken ? (_d = (_c = this.toolExecutor) == null ? void 0 : _c.getAuthToken()) != null ? _d : null : null;
1201
1236
  let analytics = {};
1202
1237
  try {
1203
- analytics = (_b2 = (_e = (_d = this.config).analyticsIds) == null ? void 0 : _e.call(_d)) != null ? _b2 : {};
1238
+ analytics = (_g = (_f = (_e = this.config).analyticsIds) == null ? void 0 : _f.call(_e)) != null ? _g : {};
1204
1239
  } catch {
1205
1240
  }
1206
1241
  const requestBody = {
@@ -1210,8 +1245,8 @@ class CopilotHarness {
1210
1245
  distinct_id: analytics.distinct_id || void 0,
1211
1246
  page_snapshot: pageSnapshot,
1212
1247
  chat_mode: chatMode || "guidance",
1213
- assistant_label: ((_f = this.config.assistantLabel) == null ? void 0 : _f.trim()) || void 0,
1214
- delegate_instruction: ((_g = this.config.delegationInstruction) == null ? void 0 : _g.trim().slice(0, 1e3)) || void 0,
1248
+ assistant_label: ((_h = this.config.assistantLabel) == null ? void 0 : _h.trim()) || void 0,
1249
+ delegate_instruction: ((_i = this.config.delegationInstruction) == null ? void 0 : _i.trim().slice(0, 1e3)) || void 0,
1215
1250
  conversation_history: conversationHistory,
1216
1251
  stream: this.api.supportsStreaming,
1217
1252
  user_token: userToken || void 0,
@@ -1219,8 +1254,8 @@ class CopilotHarness {
1219
1254
  client_tools: chatMode === "assistant" ? this.tools.definitions() : void 0,
1220
1255
  user_context: userContext,
1221
1256
  onboarding_user_id: onboardingUserId,
1222
- tool_context: this.toolContext,
1223
- client_capabilities: ((_h = this.config.clientCapabilities) == null ? void 0 : _h.length) ? this.config.clientCapabilities : void 0
1257
+ tool_context: this.contextForTools(),
1258
+ client_capabilities: ((_j2 = this.config.clientCapabilities) == null ? void 0 : _j2.length) ? this.config.clientCapabilities : void 0
1224
1259
  };
1225
1260
  let rawResponse;
1226
1261
  try {
@@ -1260,7 +1295,7 @@ class CopilotHarness {
1260
1295
  const harnessResponse = this._handleJsonResponse(response, chatMode);
1261
1296
  if (harnessResponse.autoExecuteToolCall && harnessResponse.pendingToolCall) {
1262
1297
  return this._executePendingToolCall(
1263
- (_c2 = harnessResponse.pendingToolCalls) != null ? _c2 : [harnessResponse.pendingToolCall],
1298
+ (_k = harnessResponse.pendingToolCalls) != null ? _k : [harnessResponse.pendingToolCall],
1264
1299
  sanitizedQuestion,
1265
1300
  onStatus,
1266
1301
  onTextDelta,
@@ -1585,8 +1620,7 @@ class CopilotHarness {
1585
1620
  return result.trim();
1586
1621
  }
1587
1622
  _parseStreamedResponse(response) {
1588
- var _a2;
1589
- var _a, _b, _c, _d;
1623
+ var _a, _b, _c, _d, _e;
1590
1624
  const respCheck = this.validator.validateResponse(response);
1591
1625
  const answer = respCheck.sanitized || response.answer || "";
1592
1626
  if ((_a = response.tool_call) == null ? void 0 : _a.requires_confirm) {
@@ -1616,7 +1650,7 @@ class CopilotHarness {
1616
1650
  let toolResult;
1617
1651
  if (response.tool_result) {
1618
1652
  toolResult = {
1619
- success: (_a2 = response.tool_result.success) != null ? _a2 : true,
1653
+ success: (_c = response.tool_result.success) != null ? _c : true,
1620
1654
  data: response.tool_result.data,
1621
1655
  error: response.tool_result.error,
1622
1656
  status: response.tool_result.status
@@ -1636,10 +1670,10 @@ class CopilotHarness {
1636
1670
  escalation: response.escalation || void 0,
1637
1671
  demo: response.demo || void 0,
1638
1672
  point: response.point || void 0,
1639
- actions: ((_c = response.actions) == null ? void 0 : _c.length) ? response.actions : void 0,
1673
+ actions: ((_d = response.actions) == null ? void 0 : _d.length) ? response.actions : void 0,
1640
1674
  payment: response.payment || void 0,
1641
1675
  coach: response.coach || void 0,
1642
- quickReplies: ((_d = response.quick_replies) == null ? void 0 : _d.length) ? response.quick_replies : void 0
1676
+ quickReplies: ((_e = response.quick_replies) == null ? void 0 : _e.length) ? response.quick_replies : void 0
1643
1677
  };
1644
1678
  }
1645
1679
  /**
@@ -1667,14 +1701,13 @@ class CopilotHarness {
1667
1701
  return plan;
1668
1702
  }
1669
1703
  _handleJsonResponse(response, chatMode, toolResult) {
1670
- var _a2;
1671
- var _a, _b, _c;
1704
+ var _a, _b, _c, _d;
1672
1705
  const respCheck = this.validator.validateResponse(response);
1673
1706
  if (!respCheck.valid) {
1674
1707
  return this._errorResponse(respCheck.error || "Invalid server response.");
1675
1708
  }
1676
1709
  const answer = respCheck.sanitized || response.answer;
1677
- const plan = (_a2 = this._announcePlan(response.plan)) != null ? _a2 : this.currentPlan;
1710
+ const plan = (_a = this._announcePlan(response.plan)) != null ? _a : this.currentPlan;
1678
1711
  if (response.tool_call && response.tool_call.requires_confirm) {
1679
1712
  return {
1680
1713
  mode: "answer",
@@ -1691,7 +1724,7 @@ class CopilotHarness {
1691
1724
  answer,
1692
1725
  plan,
1693
1726
  pendingToolCall: response.tool_call,
1694
- pendingToolCalls: ((_a = response.tool_calls) == null ? void 0 : _a.length) ? response.tool_calls : [response.tool_call],
1727
+ pendingToolCalls: ((_b = response.tool_calls) == null ? void 0 : _b.length) ? response.tool_calls : [response.tool_call],
1695
1728
  autoExecuteToolCall: true,
1696
1729
  autoExecute: false
1697
1730
  };
@@ -1719,10 +1752,10 @@ class CopilotHarness {
1719
1752
  escalation: response.escalation || void 0,
1720
1753
  demo: response.demo || void 0,
1721
1754
  point: response.point || void 0,
1722
- actions: ((_b = response.actions) == null ? void 0 : _b.length) ? response.actions : void 0,
1755
+ actions: ((_c = response.actions) == null ? void 0 : _c.length) ? response.actions : void 0,
1723
1756
  payment: response.payment || void 0,
1724
1757
  coach: response.coach || void 0,
1725
- quickReplies: ((_c = response.quick_replies) == null ? void 0 : _c.length) ? response.quick_replies : void 0
1758
+ quickReplies: ((_d = response.quick_replies) == null ? void 0 : _d.length) ? response.quick_replies : void 0
1726
1759
  };
1727
1760
  this.memory.addMessage({
1728
1761
  role: "assistant",
@@ -1757,7 +1790,7 @@ class CopilotHarness {
1757
1790
  tool_history: toolHistory,
1758
1791
  tools_remaining: budget == null ? void 0 : budget.toolsRemaining,
1759
1792
  force_answer: (_a = budget == null ? void 0 : budget.forceAnswer) != null ? _a : false,
1760
- tool_context: this.toolContext,
1793
+ tool_context: this.contextForTools(),
1761
1794
  client_tools: this.tools.definitions()
1762
1795
  }
1763
1796
  );
@@ -1936,12 +1969,14 @@ class CopilotHarness {
1936
1969
  return !!this.toolExecutor || this.tools.definitions().length > 0;
1937
1970
  }
1938
1971
  canExecuteTool(toolCall) {
1972
+ if (isServerTool(toolCall)) return true;
1939
1973
  if (this.tools.canExecute(toolCall.tool)) {
1940
1974
  return this.tools.canExecuteCall(toolCall);
1941
1975
  }
1942
1976
  return !!this.toolExecutor;
1943
1977
  }
1944
1978
  executeLocalTool(toolCall) {
1979
+ if (isServerTool(toolCall)) return this.executeOnServer(toolCall);
1945
1980
  if (this.tools.canExecute(toolCall.tool)) {
1946
1981
  return this.tools.execute(toolCall);
1947
1982
  }
@@ -1952,6 +1987,30 @@ class CopilotHarness {
1952
1987
  error_type: "tool_unavailable"
1953
1988
  });
1954
1989
  }
1990
+ /**
1991
+ * An MCP tool, after the user approved it: we cannot call it — it is
1992
+ * reached from GuideAI's network with a secret the client never holds —
1993
+ * so the backend runs it, told who the user is by their token.
1994
+ */
1995
+ async executeOnServer(toolCall) {
1996
+ var _a, _b;
1997
+ try {
1998
+ return await this.api.post(EP.chatExecuteTool(), {
1999
+ tool: toolCall.tool,
2000
+ method: toolCall.method,
2001
+ path: toolCall.path,
2002
+ params: toolCall.params,
2003
+ body: toolCall.body,
2004
+ user_token: (_b = (_a = this.toolExecutor) == null ? void 0 : _a.getAuthToken()) != null ? _b : void 0
2005
+ });
2006
+ } catch (error) {
2007
+ return {
2008
+ success: false,
2009
+ error: error instanceof Error ? error.message : "The tool could not be run.",
2010
+ error_type: "tool_unavailable"
2011
+ };
2012
+ }
2013
+ }
1955
2014
  executeLocalToolBatch(toolCalls, onComplete) {
1956
2015
  return Promise.all(toolCalls.map(async (toolCall) => {
1957
2016
  const result = await this.executeLocalTool(toolCall);
@@ -2349,6 +2408,7 @@ class RNCredentialSource {
2349
2408
  this.storage = storage;
2350
2409
  this.session = session;
2351
2410
  this.hostToken = null;
2411
+ this.appValues = /* @__PURE__ */ new Map();
2352
2412
  }
2353
2413
  /**
2354
2414
  * Set by the runtime from `getAuthToken()` before every turn, so the
@@ -2360,12 +2420,20 @@ class RNCredentialSource {
2360
2420
  authToken() {
2361
2421
  return this.hostToken;
2362
2422
  }
2423
+ /** Set from `getRequestHeaders()` before every turn. */
2424
+ setAppValues(values) {
2425
+ this.appValues = new Map(Object.entries(values).map(([k, v]) => [k.toLowerCase(), v]));
2426
+ }
2363
2427
  read(source, key) {
2428
+ var _a;
2364
2429
  switch (source) {
2365
2430
  case "localStorage":
2366
2431
  return this.storage.getItem(key);
2367
2432
  case "sessionStorage":
2368
2433
  return this.session.getItem(key);
2434
+ // A header the toolset declares as supplied by the app.
2435
+ case "app":
2436
+ return (_a = this.appValues.get(key.toLowerCase())) != null ? _a : null;
2369
2437
  // No cookie jar on a device. Saying so is the honest answer.
2370
2438
  case "cookie":
2371
2439
  return null;
@@ -2379,6 +2447,7 @@ function rnPlatform(options = {}) {
2379
2447
  const session = new MemoryStore();
2380
2448
  return { storage, session, credentials: new RNCredentialSource(storage, session) };
2381
2449
  }
2450
+ const RESERVED_HEADERS = /* @__PURE__ */ new Set(["authorization", "host", "content-length", "cookie"]);
2382
2451
  class HostAuth {
2383
2452
  constructor(credentials, options = {}) {
2384
2453
  this.credentials = credentials;
@@ -2391,9 +2460,24 @@ class HostAuth {
2391
2460
  current() {
2392
2461
  return this.credentials.authToken();
2393
2462
  }
2394
- /** Read the host's token now. Never throws: a failed read is "signed out". */
2463
+ /** Read the host's token and extra headers now. Never throws. */
2395
2464
  async refresh() {
2396
2465
  var _a;
2466
+ if (this.options.getRequestHeaders) {
2467
+ let raw = null;
2468
+ try {
2469
+ raw = await this.options.getRequestHeaders();
2470
+ } catch (error) {
2471
+ console.warn("[GuideAI] getRequestHeaders failed; sending none:", error);
2472
+ }
2473
+ const clean = {};
2474
+ for (const [name, value] of Object.entries(raw != null ? raw : {})) {
2475
+ if (/^[A-Za-z0-9-]{1,64}$/.test(name) && !RESERVED_HEADERS.has(name.toLowerCase()) && typeof value === "string" && value && !/[\r\n]/.test(value)) {
2476
+ clean[name] = value;
2477
+ }
2478
+ }
2479
+ this.credentials.setAppValues(clean);
2480
+ }
2397
2481
  if (!this.options.getAuthToken) return null;
2398
2482
  let token = null;
2399
2483
  try {
@@ -3160,7 +3244,7 @@ ${text}`);
3160
3244
  console.log(`${"═".repeat(60)}
3161
3245
  `);
3162
3246
  }
3163
- const DEFAULT_BASE_URL = "https://api.guideai.dev";
3247
+ const DEFAULT_BASE_URL = "https://cdn.3guideai.com";
3164
3248
  let configured = null;
3165
3249
  function configure(config) {
3166
3250
  var _a, _b, _c, _d, _e, _f;
@@ -3174,7 +3258,11 @@ function configure(config) {
3174
3258
  const runtime = new GuideAIRuntime({
3175
3259
  requestOrigin: config.origin,
3176
3260
  store: config.store,
3177
- auth: { getAuthToken: config.getAuthToken, onAuthExpired: config.onAuthExpired },
3261
+ auth: {
3262
+ getAuthToken: config.getAuthToken,
3263
+ onAuthExpired: config.onAuthExpired,
3264
+ getRequestHeaders: config.getRequestHeaders
3265
+ },
3178
3266
  navigation: config.navigation ? navigationBridge(
3179
3267
  typeof config.navigation === "function" ? config.navigation : () => config.navigation
3180
3268
  ) : void 0
@@ -3195,6 +3283,7 @@ function configure(config) {
3195
3283
  debug ? traceTransport(runtime.transport) : runtime.transport,
3196
3284
  runtime.credentials
3197
3285
  );
3286
+ if (config.toolContext) harness.setToolContext(config.toolContext);
3198
3287
  configured = {
3199
3288
  runtime,
3200
3289
  harness,
@@ -3208,6 +3297,10 @@ function identify(userId) {
3208
3297
  if (!configured) throw new Error("Call GuideAI.configure() before identify().");
3209
3298
  configured.visitorId = (userId == null ? void 0 : userId.trim()) || null;
3210
3299
  }
3300
+ function setToolContext(values) {
3301
+ if (!configured) throw new Error("Call GuideAI.configure() before setToolContext().");
3302
+ configured.harness.setToolContext(values != null ? values : void 0);
3303
+ }
3211
3304
  function setUserProfile(profile) {
3212
3305
  if (!configured) throw new Error("Call GuideAI.configure() before setUserProfile().");
3213
3306
  configured.profile = profile;
@@ -3226,7 +3319,7 @@ function isConfigured() {
3226
3319
  function reset() {
3227
3320
  configured = null;
3228
3321
  }
3229
- const GuideAI = { configure, identify, setUserProfile, isConfigured, reset };
3322
+ const GuideAI = { configure, identify, setUserProfile, setToolContext, isConfigured, reset };
3230
3323
  const AUDIO_TYPES = {
3231
3324
  m4a: "audio/m4a",
3232
3325
  mp4: "audio/mp4",
@@ -3495,4 +3588,4 @@ exports.useGuideAI = useGuideAI;
3495
3588
  exports.useGuideAIRuntime = useGuideAIRuntime;
3496
3589
  exports.useOnboarding = useOnboarding;
3497
3590
  exports.useScreenRegistry = useScreenRegistry;
3498
- //# sourceMappingURL=useOnboarding-C7eFhp2o.cjs.map
3591
+ //# sourceMappingURL=useOnboarding-DWkCW5v0.cjs.map