@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.
- package/README.md +27 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +52 -4
- package/dist/index.mjs +2 -2
- package/dist/ui.cjs +1 -1
- package/dist/ui.mjs +1 -1
- package/dist/{useOnboarding-DhVtf0U2.js → useOnboarding-DAEGoYSs.js} +120 -27
- package/dist/useOnboarding-DAEGoYSs.js.map +1 -0
- package/dist/{useOnboarding-C7eFhp2o.cjs → useOnboarding-DWkCW5v0.cjs} +120 -27
- package/dist/useOnboarding-DWkCW5v0.cjs.map +1 -0
- package/package.json +2 -2
- package/dist/useOnboarding-C7eFhp2o.cjs.map +0 -1
- package/dist/useOnboarding-DhVtf0U2.js.map +0 -1
package/README.md
CHANGED
|
@@ -24,6 +24,33 @@ GuideAI.configure({
|
|
|
24
24
|
});
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
### What else your API needs
|
|
28
|
+
|
|
29
|
+
Declare it once in the dashboard (**Copilot Tools → your API → Supplied by your app**), then supply the values:
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
GuideAI.configure({
|
|
33
|
+
…,
|
|
34
|
+
getRequestHeaders: async () => ({ 'device-id': await getDeviceId() }), // declared headers
|
|
35
|
+
toolContext: { course: openCourseId }, // declared values; or GuideAI.setToolContext(…) later
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- **Headers:** sent on every call the assistant makes to your API, never to GuideAI. Only names declared in Copilot Tools are sent, and the app's value wins over anything the model sets. `Authorization` comes from `getAuthToken`, never from here.
|
|
40
|
+
- **Values:** each one fills the API inputs it's declared to fill (app key `course` fills `content_id`), so the assistant never asks the user for them.
|
|
41
|
+
|
|
42
|
+
The dashboard shows the exact snippet for your declarations.
|
|
43
|
+
|
|
44
|
+
### Local or staging GuideAI
|
|
45
|
+
|
|
46
|
+
Production is the default. Point a development build somewhere else with `baseUrl`:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
GuideAI.configure({ …, baseUrl: __DEV__ ? 'http://localhost:8000' : undefined });
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Use `http://10.0.2.2:8000` from an Android emulator.
|
|
53
|
+
|
|
27
54
|
`userProfile` is a few facts the agent pitches answers to (level, curriculum, language). Update it after login with `GuideAI.setUserProfile(profile)`.
|
|
28
55
|
|
|
29
56
|
`getAuthToken` is read before every turn and may be async. The assistant calls your endpoints (the site's Copilot toolset) from the device with that token, so your API enforces the user's access exactly as it does for your own screens. A `401` asks `onAuthExpired` once and repeats the call. The token is sent only to your API, never to GuideAI, unless the toolset has `forward_user_token` switched on.
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const useOnboarding = require("./useOnboarding-
|
|
3
|
+
const useOnboarding = require("./useOnboarding-DWkCW5v0.cjs");
|
|
4
4
|
const jsxRuntime = require("react/jsx-runtime");
|
|
5
5
|
const React = require("react");
|
|
6
6
|
function GuideAIScreen({
|
package/dist/index.d.ts
CHANGED
|
@@ -342,6 +342,9 @@ interface OnboardingLauncher {
|
|
|
342
342
|
interface OnboardingAppearance {
|
|
343
343
|
template: 'classic' | 'minimal' | 'bold';
|
|
344
344
|
accent_color: string;
|
|
345
|
+
/** Optional checklist surface and text colours; missing values use the SDK theme. */
|
|
346
|
+
background_color?: string | null;
|
|
347
|
+
text_color?: string | null;
|
|
345
348
|
/** Missing means the default card; position missing means left. */
|
|
346
349
|
layout?: 'card' | 'modal' | 'side';
|
|
347
350
|
position?: 'left' | 'right';
|
|
@@ -471,7 +474,8 @@ interface KVStore {
|
|
|
471
474
|
}
|
|
472
475
|
/**
|
|
473
476
|
* Where a host keeps credentials the copilot may read, named by the
|
|
474
|
-
* source a site configured (`localStorage`, `sessionStorage`, `cookie`)
|
|
477
|
+
* source a site configured (`localStorage`, `sessionStorage`, `cookie`),
|
|
478
|
+
* or `app` for values the host app hands over itself (declared headers).
|
|
475
479
|
*
|
|
476
480
|
* Returns null for a source this platform does not have. A mobile app has
|
|
477
481
|
* no cookie jar, and saying so plainly is better than returning an empty
|
|
@@ -479,6 +483,15 @@ interface KVStore {
|
|
|
479
483
|
*/
|
|
480
484
|
interface CredentialSource {
|
|
481
485
|
read(source: string, key: string): string | null;
|
|
486
|
+
/**
|
|
487
|
+
* The signed-in user's bearer token, when the host hands it over itself.
|
|
488
|
+
*
|
|
489
|
+
* A native app keeps its token where it chooses (SecureStore,
|
|
490
|
+
* AsyncStorage), not in a store the site's dashboard can name. When this
|
|
491
|
+
* returns a token it wins over the configured storage lookup for a
|
|
492
|
+
* `bearer` toolset; null falls back to that lookup.
|
|
493
|
+
*/
|
|
494
|
+
authToken?(): string | null;
|
|
482
495
|
}
|
|
483
496
|
|
|
484
497
|
/**
|
|
@@ -639,6 +652,12 @@ declare class CopilotHarness {
|
|
|
639
652
|
distinct_id?: string;
|
|
640
653
|
}): void;
|
|
641
654
|
setToolContext(values: Record<string, string> | undefined): void;
|
|
655
|
+
/**
|
|
656
|
+
* The app's tool inputs as the API names them. A value declared in Copilot
|
|
657
|
+
* Tools as filling other inputs (app key `course` fills `content_id`) is
|
|
658
|
+
* sent under those names too; one the app set by that name already wins.
|
|
659
|
+
*/
|
|
660
|
+
private contextForTools;
|
|
642
661
|
/** Whether copilot action tools are available for this site. */
|
|
643
662
|
isEnabled(): boolean;
|
|
644
663
|
/**
|
|
@@ -726,6 +745,12 @@ declare class CopilotHarness {
|
|
|
726
745
|
private hasAnyLocalTools;
|
|
727
746
|
private canExecuteTool;
|
|
728
747
|
private executeLocalTool;
|
|
748
|
+
/**
|
|
749
|
+
* An MCP tool, after the user approved it: we cannot call it — it is
|
|
750
|
+
* reached from GuideAI's network with a secret the client never holds —
|
|
751
|
+
* so the backend runs it, told who the user is by their token.
|
|
752
|
+
*/
|
|
753
|
+
private executeOnServer;
|
|
729
754
|
private executeLocalToolBatch;
|
|
730
755
|
private _formatToolResult;
|
|
731
756
|
private _readFormatToolResultStream;
|
|
@@ -755,6 +780,12 @@ interface SyncNativeStore {
|
|
|
755
780
|
|
|
756
781
|
/** Returns the signed-in user's token, or null when signed out. May be async. */
|
|
757
782
|
type AuthTokenGetter = () => string | null | undefined | Promise<string | null | undefined>;
|
|
783
|
+
/**
|
|
784
|
+
* Values for the headers the site's toolset declares as supplied by the app
|
|
785
|
+
* (Copilot Tools → "Supplied by your app"). May be async. Only declared
|
|
786
|
+
* names are ever sent.
|
|
787
|
+
*/
|
|
788
|
+
type RequestHeadersGetter = () => Record<string, string> | null | undefined | Promise<Record<string, string> | null | undefined>;
|
|
758
789
|
|
|
759
790
|
/** What a host says about one control on screen. */
|
|
760
791
|
interface DeclaredElement {
|
|
@@ -820,8 +851,8 @@ interface GuideAIConfig {
|
|
|
820
851
|
*/
|
|
821
852
|
origin?: string;
|
|
822
853
|
/**
|
|
823
|
-
* Where the GuideAI backend lives. Defaults to
|
|
824
|
-
*
|
|
854
|
+
* Where the GuideAI backend lives. Defaults to production; set it to test
|
|
855
|
+
* against a local or staging GuideAI (`http://localhost:8000`).
|
|
825
856
|
*/
|
|
826
857
|
baseUrl?: string;
|
|
827
858
|
/**
|
|
@@ -856,6 +887,20 @@ interface GuideAIConfig {
|
|
|
856
887
|
* Omitted: getAuthToken() is asked again.
|
|
857
888
|
*/
|
|
858
889
|
onAuthExpired?: AuthTokenGetter;
|
|
890
|
+
/**
|
|
891
|
+
* Values for the headers your toolset declares in Copilot Tools as
|
|
892
|
+
* "Supplied by your app" — a device id, a tenant: `async () => ({
|
|
893
|
+
* 'device-id': id })`. Read before every turn; sent only to your API,
|
|
894
|
+
* never to GuideAI, and only for declared names.
|
|
895
|
+
*/
|
|
896
|
+
getRequestHeaders?: RequestHeadersGetter;
|
|
897
|
+
/**
|
|
898
|
+
* Values the app knows right now — the course open on screen: `{ course:
|
|
899
|
+
* '42' }`. Each fills the API inputs of the same name, or those the
|
|
900
|
+
* toolset declares it fills (Copilot Tools → "Supplied by your app").
|
|
901
|
+
* Change it with GuideAI.setToolContext().
|
|
902
|
+
*/
|
|
903
|
+
toolContext?: Record<string, string>;
|
|
859
904
|
/**
|
|
860
905
|
* Facts about the signed-in user for the agent to pitch answers to —
|
|
861
906
|
* `{ age: 12, class: 'JSS1', country: 'Nigeria', language: 'en' }`.
|
|
@@ -880,6 +925,8 @@ type GuideAIUserProfile = Record<string, string | number | boolean | Array<strin
|
|
|
880
925
|
declare function configure(config: GuideAIConfig): void;
|
|
881
926
|
/** Call after login so chat and the checklist use the same person. */
|
|
882
927
|
declare function identify(userId: string | null): void;
|
|
928
|
+
/** Replace the tool inputs the app knows now (e.g. when another course opens). */
|
|
929
|
+
declare function setToolContext(values: Record<string, string> | null): void;
|
|
883
930
|
/** Replace what the agent knows about the user (after login, or a profile edit). */
|
|
884
931
|
declare function setUserProfile(profile: GuideAIUserProfile | null): void;
|
|
885
932
|
/** Whether configure() has run. Lets a host render its own fallback. */
|
|
@@ -890,6 +937,7 @@ declare const GuideAI: {
|
|
|
890
937
|
configure: typeof configure;
|
|
891
938
|
identify: typeof identify;
|
|
892
939
|
setUserProfile: typeof setUserProfile;
|
|
940
|
+
setToolContext: typeof setToolContext;
|
|
893
941
|
isConfigured: typeof isConfigured;
|
|
894
942
|
reset: typeof reset;
|
|
895
943
|
};
|
|
@@ -1040,4 +1088,4 @@ declare function useOnboarding(): {
|
|
|
1040
1088
|
};
|
|
1041
1089
|
|
|
1042
1090
|
export { GuideAI, GuideAIScreen, useGuideAI, useGuideAIElement, useOnboarding };
|
|
1043
|
-
export type { AuthTokenGetter, DeclaredElement, ElementHandlers, GuideAIConfig, HeadlessImage as GuideAIImage, GuideAIMessage, GuideAIScreenProps, GuideAIUserProfile, GuideAIVoiceRecording, GuideAIVoiceResult, NavigationRefLike, OnboardingState, OnboardingStepState, SyncNativeStore, UseGuideAIElementOptions, UseGuideAIResult };
|
|
1091
|
+
export type { AuthTokenGetter, DeclaredElement, ElementHandlers, GuideAIConfig, HeadlessImage as GuideAIImage, GuideAIMessage, GuideAIScreenProps, GuideAIUserProfile, GuideAIVoiceRecording, GuideAIVoiceResult, NavigationRefLike, OnboardingState, OnboardingStepState, RequestHeadersGetter, SyncNativeStore, UseGuideAIElementOptions, UseGuideAIResult };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { u as useGuideAIRuntime, S as ScreenRegistry, R as RegistryContext, a as useScreenRegistry } from "./useOnboarding-
|
|
2
|
-
import { G, b, c } from "./useOnboarding-
|
|
1
|
+
import { u as useGuideAIRuntime, S as ScreenRegistry, R as RegistryContext, a as useScreenRegistry } from "./useOnboarding-DAEGoYSs.js";
|
|
2
|
+
import { G, b, c } from "./useOnboarding-DAEGoYSs.js";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import { useMemo, useEffect, useRef } from "react";
|
|
5
5
|
function GuideAIScreen({
|
package/dist/ui.cjs
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
4
|
const React = require("react");
|
|
5
5
|
const reactNative = require("react-native");
|
|
6
|
-
const useOnboarding = require("./useOnboarding-
|
|
6
|
+
const useOnboarding = require("./useOnboarding-DWkCW5v0.cjs");
|
|
7
7
|
function parseInline(text) {
|
|
8
8
|
const spans = [];
|
|
9
9
|
const pattern = /(`[^`]+`)|(\*\*[^*]+\*\*)|(__[^_]+__)|(\*[^*\n]+\*)|(_[^_\n]+_)|(\[[^\]]+\]\([^)]+\))/g;
|
package/dist/ui.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import React, { useRef, useState, useEffect, useCallback, useMemo, useContext, createContext } from "react";
|
|
3
3
|
import { View, StyleSheet, Text, ScrollView, Linking, KeyboardAvoidingView, Pressable, Alert, FlatList, ActivityIndicator, TextInput, Platform, StatusBar, Animated, Easing, Dimensions, PanResponder, Modal } from "react-native";
|
|
4
|
-
import { r as requireConfigured, b as useGuideAI, c as useOnboarding, E as EP } from "./useOnboarding-
|
|
4
|
+
import { r as requireConfigured, b as useGuideAI, c as useOnboarding, E as EP } from "./useOnboarding-DAEGoYSs.js";
|
|
5
5
|
function parseInline(text) {
|
|
6
6
|
const spans = [];
|
|
7
7
|
const pattern = /(`[^`]+`)|(\*\*[^*]+\*\*)|(__[^_]+__)|(\*[^*\n]+\*)|(_[^_\n]+_)|(\[[^\]]+\]\([^)]+\))/g;
|
|
@@ -83,7 +83,7 @@ function describeToolCall(toolCall) {
|
|
|
83
83
|
const ownScope = /\s+(me|self|current|mine)$/.test(noun);
|
|
84
84
|
if (ownScope) noun = `your ${noun.replace(/\s+(me|self|current|mine)$/, "")}`;
|
|
85
85
|
if (SELF_DESCRIBING.test(noun) || ownScope) return `${verb} ${noun}`;
|
|
86
|
-
const singular = noun.replace(
|
|
86
|
+
const singular = noun.replace(/([a-z])(?<!s|u|i)s$/, "$1");
|
|
87
87
|
return `${verb} ${singular} information`;
|
|
88
88
|
}
|
|
89
89
|
function describeToolBatch(toolCalls) {
|
|
@@ -651,8 +651,11 @@ class ToolExecutor {
|
|
|
651
651
|
}
|
|
652
652
|
/** Read the user's auth token from the configured browser storage. */
|
|
653
653
|
getAuthToken() {
|
|
654
|
+
var _a, _b;
|
|
654
655
|
if (this.authConfig.type === "none") return null;
|
|
655
656
|
try {
|
|
657
|
+
const supplied = this.authConfig.type === "bearer" ? (_b = (_a = this.credentials).authToken) == null ? void 0 : _b.call(_a) : null;
|
|
658
|
+
if (supplied) return supplied;
|
|
656
659
|
let raw = null;
|
|
657
660
|
const storageKey = this.authConfig.key;
|
|
658
661
|
if (storageKey && this.authConfig.source) {
|
|
@@ -838,6 +841,7 @@ class ToolExecutor {
|
|
|
838
841
|
});
|
|
839
842
|
}
|
|
840
843
|
_buildHeaders(toolCall) {
|
|
844
|
+
var _a;
|
|
841
845
|
const headers = {
|
|
842
846
|
"Content-Type": "application/json",
|
|
843
847
|
Accept: "application/json"
|
|
@@ -884,6 +888,16 @@ class ToolExecutor {
|
|
|
884
888
|
mergeHeader(name, value);
|
|
885
889
|
}
|
|
886
890
|
}
|
|
891
|
+
for (const declared of (_a = this.authConfig.app_headers) != null ? _a : []) {
|
|
892
|
+
if (!(declared == null ? void 0 : declared.name)) continue;
|
|
893
|
+
let value = null;
|
|
894
|
+
try {
|
|
895
|
+
value = this.credentials.read("app", declared.name);
|
|
896
|
+
} catch {
|
|
897
|
+
value = null;
|
|
898
|
+
}
|
|
899
|
+
mergeHeader(declared.name, value);
|
|
900
|
+
}
|
|
887
901
|
return headers;
|
|
888
902
|
}
|
|
889
903
|
_resolveHeaderValue(value) {
|
|
@@ -1026,6 +1040,7 @@ const EP = {
|
|
|
1026
1040
|
guidesRecord: () => _j([..._v, "guides", "record"]),
|
|
1027
1041
|
events: () => _j([..._v, "events"]),
|
|
1028
1042
|
chatAsk: () => _j([..._v, "chat", "ask"]),
|
|
1043
|
+
chatExecuteTool: () => _j([..._v, "chat", "execute-tool"]),
|
|
1029
1044
|
onboardingCurrent: (userId) => `${_j([..._v, "onboarding", "current"])}?user_id=${encodeURIComponent(userId)}`,
|
|
1030
1045
|
onboardingObserve: () => _j([..._v, "onboarding", "observe"]),
|
|
1031
1046
|
onboardingDismiss: () => _j([..._v, "onboarding", "dismiss"]),
|
|
@@ -1083,6 +1098,9 @@ const MAX_CHAIN_ROUNDS = 5;
|
|
|
1083
1098
|
const MAX_TOTAL_TOOL_CALLS = 10;
|
|
1084
1099
|
const MAX_REPAIR_ROUNDS = 1;
|
|
1085
1100
|
const REPAIRABLE_ERROR_TYPES = /* @__PURE__ */ new Set(["validation", "client", "not_found"]);
|
|
1101
|
+
function isServerTool(toolCall) {
|
|
1102
|
+
return (toolCall.method || "").toUpperCase() === "MCP";
|
|
1103
|
+
}
|
|
1086
1104
|
class CopilotHarness {
|
|
1087
1105
|
/**
|
|
1088
1106
|
* @param tools How this platform actually touches the screen. Defaults to
|
|
@@ -1166,6 +1184,24 @@ class CopilotHarness {
|
|
|
1166
1184
|
setToolContext(values) {
|
|
1167
1185
|
this.toolContext = values && Object.keys(values).length > 0 ? values : void 0;
|
|
1168
1186
|
}
|
|
1187
|
+
/**
|
|
1188
|
+
* The app's tool inputs as the API names them. A value declared in Copilot
|
|
1189
|
+
* Tools as filling other inputs (app key `course` fills `content_id`) is
|
|
1190
|
+
* sent under those names too; one the app set by that name already wins.
|
|
1191
|
+
*/
|
|
1192
|
+
contextForTools() {
|
|
1193
|
+
var _a, _b, _c, _d;
|
|
1194
|
+
if (!this.toolContext) return void 0;
|
|
1195
|
+
const out = { ...this.toolContext };
|
|
1196
|
+
for (const input of (_c = (_b = (_a = this.activeTools) == null ? void 0 : _a.auth_config) == null ? void 0 : _b.app_inputs) != null ? _c : []) {
|
|
1197
|
+
const value = (input == null ? void 0 : input.key) ? this.toolContext[input.key] : void 0;
|
|
1198
|
+
if (value === void 0) continue;
|
|
1199
|
+
for (const name of (_d = input.fills) != null ? _d : []) {
|
|
1200
|
+
if (name && !(name in out)) out[name] = value;
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
return out;
|
|
1204
|
+
}
|
|
1169
1205
|
/** Whether copilot action tools are available for this site. */
|
|
1170
1206
|
isEnabled() {
|
|
1171
1207
|
return this.tools.definitions().length > 0 || this.activeTools !== null && this.activeTools.tools.length > 0;
|
|
@@ -1180,8 +1216,7 @@ class CopilotHarness {
|
|
|
1180
1216
|
* 5. For non-tool queries, returns JSON response directly
|
|
1181
1217
|
*/
|
|
1182
1218
|
async processMessage(question, pageUrl, pageSnapshot, chatMode, onStatus, onTextDelta, onToolCallEvent, abortSignal, userContext, onboardingUserId) {
|
|
1183
|
-
var
|
|
1184
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1219
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j2, _k;
|
|
1185
1220
|
const inputCheck = this.validator.validateUserInput(question);
|
|
1186
1221
|
if (!inputCheck.valid) {
|
|
1187
1222
|
return this._errorResponse(inputCheck.error || "Invalid input.");
|
|
@@ -1196,10 +1231,10 @@ class CopilotHarness {
|
|
|
1196
1231
|
});
|
|
1197
1232
|
const conversationHistory = this.memory.getRecentForLLM(10);
|
|
1198
1233
|
const mayForwardToken = ((_b = (_a = this.activeTools) == null ? void 0 : _a.auth_config) == null ? void 0 : _b.forward_user_token) === true;
|
|
1199
|
-
const userToken = mayForwardToken ? (
|
|
1234
|
+
const userToken = mayForwardToken ? (_d = (_c = this.toolExecutor) == null ? void 0 : _c.getAuthToken()) != null ? _d : null : null;
|
|
1200
1235
|
let analytics = {};
|
|
1201
1236
|
try {
|
|
1202
|
-
analytics = (
|
|
1237
|
+
analytics = (_g = (_f = (_e = this.config).analyticsIds) == null ? void 0 : _f.call(_e)) != null ? _g : {};
|
|
1203
1238
|
} catch {
|
|
1204
1239
|
}
|
|
1205
1240
|
const requestBody = {
|
|
@@ -1209,8 +1244,8 @@ class CopilotHarness {
|
|
|
1209
1244
|
distinct_id: analytics.distinct_id || void 0,
|
|
1210
1245
|
page_snapshot: pageSnapshot,
|
|
1211
1246
|
chat_mode: chatMode || "guidance",
|
|
1212
|
-
assistant_label: ((
|
|
1213
|
-
delegate_instruction: ((
|
|
1247
|
+
assistant_label: ((_h = this.config.assistantLabel) == null ? void 0 : _h.trim()) || void 0,
|
|
1248
|
+
delegate_instruction: ((_i = this.config.delegationInstruction) == null ? void 0 : _i.trim().slice(0, 1e3)) || void 0,
|
|
1214
1249
|
conversation_history: conversationHistory,
|
|
1215
1250
|
stream: this.api.supportsStreaming,
|
|
1216
1251
|
user_token: userToken || void 0,
|
|
@@ -1218,8 +1253,8 @@ class CopilotHarness {
|
|
|
1218
1253
|
client_tools: chatMode === "assistant" ? this.tools.definitions() : void 0,
|
|
1219
1254
|
user_context: userContext,
|
|
1220
1255
|
onboarding_user_id: onboardingUserId,
|
|
1221
|
-
tool_context: this.
|
|
1222
|
-
client_capabilities: ((
|
|
1256
|
+
tool_context: this.contextForTools(),
|
|
1257
|
+
client_capabilities: ((_j2 = this.config.clientCapabilities) == null ? void 0 : _j2.length) ? this.config.clientCapabilities : void 0
|
|
1223
1258
|
};
|
|
1224
1259
|
let rawResponse;
|
|
1225
1260
|
try {
|
|
@@ -1259,7 +1294,7 @@ class CopilotHarness {
|
|
|
1259
1294
|
const harnessResponse = this._handleJsonResponse(response, chatMode);
|
|
1260
1295
|
if (harnessResponse.autoExecuteToolCall && harnessResponse.pendingToolCall) {
|
|
1261
1296
|
return this._executePendingToolCall(
|
|
1262
|
-
(
|
|
1297
|
+
(_k = harnessResponse.pendingToolCalls) != null ? _k : [harnessResponse.pendingToolCall],
|
|
1263
1298
|
sanitizedQuestion,
|
|
1264
1299
|
onStatus,
|
|
1265
1300
|
onTextDelta,
|
|
@@ -1584,8 +1619,7 @@ class CopilotHarness {
|
|
|
1584
1619
|
return result.trim();
|
|
1585
1620
|
}
|
|
1586
1621
|
_parseStreamedResponse(response) {
|
|
1587
|
-
var
|
|
1588
|
-
var _a, _b, _c, _d;
|
|
1622
|
+
var _a, _b, _c, _d, _e;
|
|
1589
1623
|
const respCheck = this.validator.validateResponse(response);
|
|
1590
1624
|
const answer = respCheck.sanitized || response.answer || "";
|
|
1591
1625
|
if ((_a = response.tool_call) == null ? void 0 : _a.requires_confirm) {
|
|
@@ -1615,7 +1649,7 @@ class CopilotHarness {
|
|
|
1615
1649
|
let toolResult;
|
|
1616
1650
|
if (response.tool_result) {
|
|
1617
1651
|
toolResult = {
|
|
1618
|
-
success: (
|
|
1652
|
+
success: (_c = response.tool_result.success) != null ? _c : true,
|
|
1619
1653
|
data: response.tool_result.data,
|
|
1620
1654
|
error: response.tool_result.error,
|
|
1621
1655
|
status: response.tool_result.status
|
|
@@ -1635,10 +1669,10 @@ class CopilotHarness {
|
|
|
1635
1669
|
escalation: response.escalation || void 0,
|
|
1636
1670
|
demo: response.demo || void 0,
|
|
1637
1671
|
point: response.point || void 0,
|
|
1638
|
-
actions: ((
|
|
1672
|
+
actions: ((_d = response.actions) == null ? void 0 : _d.length) ? response.actions : void 0,
|
|
1639
1673
|
payment: response.payment || void 0,
|
|
1640
1674
|
coach: response.coach || void 0,
|
|
1641
|
-
quickReplies: ((
|
|
1675
|
+
quickReplies: ((_e = response.quick_replies) == null ? void 0 : _e.length) ? response.quick_replies : void 0
|
|
1642
1676
|
};
|
|
1643
1677
|
}
|
|
1644
1678
|
/**
|
|
@@ -1666,14 +1700,13 @@ class CopilotHarness {
|
|
|
1666
1700
|
return plan;
|
|
1667
1701
|
}
|
|
1668
1702
|
_handleJsonResponse(response, chatMode, toolResult) {
|
|
1669
|
-
var
|
|
1670
|
-
var _a, _b, _c;
|
|
1703
|
+
var _a, _b, _c, _d;
|
|
1671
1704
|
const respCheck = this.validator.validateResponse(response);
|
|
1672
1705
|
if (!respCheck.valid) {
|
|
1673
1706
|
return this._errorResponse(respCheck.error || "Invalid server response.");
|
|
1674
1707
|
}
|
|
1675
1708
|
const answer = respCheck.sanitized || response.answer;
|
|
1676
|
-
const plan = (
|
|
1709
|
+
const plan = (_a = this._announcePlan(response.plan)) != null ? _a : this.currentPlan;
|
|
1677
1710
|
if (response.tool_call && response.tool_call.requires_confirm) {
|
|
1678
1711
|
return {
|
|
1679
1712
|
mode: "answer",
|
|
@@ -1690,7 +1723,7 @@ class CopilotHarness {
|
|
|
1690
1723
|
answer,
|
|
1691
1724
|
plan,
|
|
1692
1725
|
pendingToolCall: response.tool_call,
|
|
1693
|
-
pendingToolCalls: ((
|
|
1726
|
+
pendingToolCalls: ((_b = response.tool_calls) == null ? void 0 : _b.length) ? response.tool_calls : [response.tool_call],
|
|
1694
1727
|
autoExecuteToolCall: true,
|
|
1695
1728
|
autoExecute: false
|
|
1696
1729
|
};
|
|
@@ -1718,10 +1751,10 @@ class CopilotHarness {
|
|
|
1718
1751
|
escalation: response.escalation || void 0,
|
|
1719
1752
|
demo: response.demo || void 0,
|
|
1720
1753
|
point: response.point || void 0,
|
|
1721
|
-
actions: ((
|
|
1754
|
+
actions: ((_c = response.actions) == null ? void 0 : _c.length) ? response.actions : void 0,
|
|
1722
1755
|
payment: response.payment || void 0,
|
|
1723
1756
|
coach: response.coach || void 0,
|
|
1724
|
-
quickReplies: ((
|
|
1757
|
+
quickReplies: ((_d = response.quick_replies) == null ? void 0 : _d.length) ? response.quick_replies : void 0
|
|
1725
1758
|
};
|
|
1726
1759
|
this.memory.addMessage({
|
|
1727
1760
|
role: "assistant",
|
|
@@ -1756,7 +1789,7 @@ class CopilotHarness {
|
|
|
1756
1789
|
tool_history: toolHistory,
|
|
1757
1790
|
tools_remaining: budget == null ? void 0 : budget.toolsRemaining,
|
|
1758
1791
|
force_answer: (_a = budget == null ? void 0 : budget.forceAnswer) != null ? _a : false,
|
|
1759
|
-
tool_context: this.
|
|
1792
|
+
tool_context: this.contextForTools(),
|
|
1760
1793
|
client_tools: this.tools.definitions()
|
|
1761
1794
|
}
|
|
1762
1795
|
);
|
|
@@ -1935,12 +1968,14 @@ class CopilotHarness {
|
|
|
1935
1968
|
return !!this.toolExecutor || this.tools.definitions().length > 0;
|
|
1936
1969
|
}
|
|
1937
1970
|
canExecuteTool(toolCall) {
|
|
1971
|
+
if (isServerTool(toolCall)) return true;
|
|
1938
1972
|
if (this.tools.canExecute(toolCall.tool)) {
|
|
1939
1973
|
return this.tools.canExecuteCall(toolCall);
|
|
1940
1974
|
}
|
|
1941
1975
|
return !!this.toolExecutor;
|
|
1942
1976
|
}
|
|
1943
1977
|
executeLocalTool(toolCall) {
|
|
1978
|
+
if (isServerTool(toolCall)) return this.executeOnServer(toolCall);
|
|
1944
1979
|
if (this.tools.canExecute(toolCall.tool)) {
|
|
1945
1980
|
return this.tools.execute(toolCall);
|
|
1946
1981
|
}
|
|
@@ -1951,6 +1986,30 @@ class CopilotHarness {
|
|
|
1951
1986
|
error_type: "tool_unavailable"
|
|
1952
1987
|
});
|
|
1953
1988
|
}
|
|
1989
|
+
/**
|
|
1990
|
+
* An MCP tool, after the user approved it: we cannot call it — it is
|
|
1991
|
+
* reached from GuideAI's network with a secret the client never holds —
|
|
1992
|
+
* so the backend runs it, told who the user is by their token.
|
|
1993
|
+
*/
|
|
1994
|
+
async executeOnServer(toolCall) {
|
|
1995
|
+
var _a, _b;
|
|
1996
|
+
try {
|
|
1997
|
+
return await this.api.post(EP.chatExecuteTool(), {
|
|
1998
|
+
tool: toolCall.tool,
|
|
1999
|
+
method: toolCall.method,
|
|
2000
|
+
path: toolCall.path,
|
|
2001
|
+
params: toolCall.params,
|
|
2002
|
+
body: toolCall.body,
|
|
2003
|
+
user_token: (_b = (_a = this.toolExecutor) == null ? void 0 : _a.getAuthToken()) != null ? _b : void 0
|
|
2004
|
+
});
|
|
2005
|
+
} catch (error) {
|
|
2006
|
+
return {
|
|
2007
|
+
success: false,
|
|
2008
|
+
error: error instanceof Error ? error.message : "The tool could not be run.",
|
|
2009
|
+
error_type: "tool_unavailable"
|
|
2010
|
+
};
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
1954
2013
|
executeLocalToolBatch(toolCalls, onComplete) {
|
|
1955
2014
|
return Promise.all(toolCalls.map(async (toolCall) => {
|
|
1956
2015
|
const result = await this.executeLocalTool(toolCall);
|
|
@@ -2348,6 +2407,7 @@ class RNCredentialSource {
|
|
|
2348
2407
|
this.storage = storage;
|
|
2349
2408
|
this.session = session;
|
|
2350
2409
|
this.hostToken = null;
|
|
2410
|
+
this.appValues = /* @__PURE__ */ new Map();
|
|
2351
2411
|
}
|
|
2352
2412
|
/**
|
|
2353
2413
|
* Set by the runtime from `getAuthToken()` before every turn, so the
|
|
@@ -2359,12 +2419,20 @@ class RNCredentialSource {
|
|
|
2359
2419
|
authToken() {
|
|
2360
2420
|
return this.hostToken;
|
|
2361
2421
|
}
|
|
2422
|
+
/** Set from `getRequestHeaders()` before every turn. */
|
|
2423
|
+
setAppValues(values) {
|
|
2424
|
+
this.appValues = new Map(Object.entries(values).map(([k, v]) => [k.toLowerCase(), v]));
|
|
2425
|
+
}
|
|
2362
2426
|
read(source, key) {
|
|
2427
|
+
var _a;
|
|
2363
2428
|
switch (source) {
|
|
2364
2429
|
case "localStorage":
|
|
2365
2430
|
return this.storage.getItem(key);
|
|
2366
2431
|
case "sessionStorage":
|
|
2367
2432
|
return this.session.getItem(key);
|
|
2433
|
+
// A header the toolset declares as supplied by the app.
|
|
2434
|
+
case "app":
|
|
2435
|
+
return (_a = this.appValues.get(key.toLowerCase())) != null ? _a : null;
|
|
2368
2436
|
// No cookie jar on a device. Saying so is the honest answer.
|
|
2369
2437
|
case "cookie":
|
|
2370
2438
|
return null;
|
|
@@ -2378,6 +2446,7 @@ function rnPlatform(options = {}) {
|
|
|
2378
2446
|
const session = new MemoryStore();
|
|
2379
2447
|
return { storage, session, credentials: new RNCredentialSource(storage, session) };
|
|
2380
2448
|
}
|
|
2449
|
+
const RESERVED_HEADERS = /* @__PURE__ */ new Set(["authorization", "host", "content-length", "cookie"]);
|
|
2381
2450
|
class HostAuth {
|
|
2382
2451
|
constructor(credentials, options = {}) {
|
|
2383
2452
|
this.credentials = credentials;
|
|
@@ -2390,9 +2459,24 @@ class HostAuth {
|
|
|
2390
2459
|
current() {
|
|
2391
2460
|
return this.credentials.authToken();
|
|
2392
2461
|
}
|
|
2393
|
-
/** Read the host's token now. Never throws
|
|
2462
|
+
/** Read the host's token and extra headers now. Never throws. */
|
|
2394
2463
|
async refresh() {
|
|
2395
2464
|
var _a;
|
|
2465
|
+
if (this.options.getRequestHeaders) {
|
|
2466
|
+
let raw = null;
|
|
2467
|
+
try {
|
|
2468
|
+
raw = await this.options.getRequestHeaders();
|
|
2469
|
+
} catch (error) {
|
|
2470
|
+
console.warn("[GuideAI] getRequestHeaders failed; sending none:", error);
|
|
2471
|
+
}
|
|
2472
|
+
const clean = {};
|
|
2473
|
+
for (const [name, value] of Object.entries(raw != null ? raw : {})) {
|
|
2474
|
+
if (/^[A-Za-z0-9-]{1,64}$/.test(name) && !RESERVED_HEADERS.has(name.toLowerCase()) && typeof value === "string" && value && !/[\r\n]/.test(value)) {
|
|
2475
|
+
clean[name] = value;
|
|
2476
|
+
}
|
|
2477
|
+
}
|
|
2478
|
+
this.credentials.setAppValues(clean);
|
|
2479
|
+
}
|
|
2396
2480
|
if (!this.options.getAuthToken) return null;
|
|
2397
2481
|
let token = null;
|
|
2398
2482
|
try {
|
|
@@ -3159,7 +3243,7 @@ ${text}`);
|
|
|
3159
3243
|
console.log(`${"═".repeat(60)}
|
|
3160
3244
|
`);
|
|
3161
3245
|
}
|
|
3162
|
-
const DEFAULT_BASE_URL = "https://
|
|
3246
|
+
const DEFAULT_BASE_URL = "https://cdn.3guideai.com";
|
|
3163
3247
|
let configured = null;
|
|
3164
3248
|
function configure(config) {
|
|
3165
3249
|
var _a, _b, _c, _d, _e, _f;
|
|
@@ -3173,7 +3257,11 @@ function configure(config) {
|
|
|
3173
3257
|
const runtime = new GuideAIRuntime({
|
|
3174
3258
|
requestOrigin: config.origin,
|
|
3175
3259
|
store: config.store,
|
|
3176
|
-
auth: {
|
|
3260
|
+
auth: {
|
|
3261
|
+
getAuthToken: config.getAuthToken,
|
|
3262
|
+
onAuthExpired: config.onAuthExpired,
|
|
3263
|
+
getRequestHeaders: config.getRequestHeaders
|
|
3264
|
+
},
|
|
3177
3265
|
navigation: config.navigation ? navigationBridge(
|
|
3178
3266
|
typeof config.navigation === "function" ? config.navigation : () => config.navigation
|
|
3179
3267
|
) : void 0
|
|
@@ -3194,6 +3282,7 @@ function configure(config) {
|
|
|
3194
3282
|
debug ? traceTransport(runtime.transport) : runtime.transport,
|
|
3195
3283
|
runtime.credentials
|
|
3196
3284
|
);
|
|
3285
|
+
if (config.toolContext) harness.setToolContext(config.toolContext);
|
|
3197
3286
|
configured = {
|
|
3198
3287
|
runtime,
|
|
3199
3288
|
harness,
|
|
@@ -3207,6 +3296,10 @@ function identify(userId) {
|
|
|
3207
3296
|
if (!configured) throw new Error("Call GuideAI.configure() before identify().");
|
|
3208
3297
|
configured.visitorId = (userId == null ? void 0 : userId.trim()) || null;
|
|
3209
3298
|
}
|
|
3299
|
+
function setToolContext(values) {
|
|
3300
|
+
if (!configured) throw new Error("Call GuideAI.configure() before setToolContext().");
|
|
3301
|
+
configured.harness.setToolContext(values != null ? values : void 0);
|
|
3302
|
+
}
|
|
3210
3303
|
function setUserProfile(profile) {
|
|
3211
3304
|
if (!configured) throw new Error("Call GuideAI.configure() before setUserProfile().");
|
|
3212
3305
|
configured.profile = profile;
|
|
@@ -3225,7 +3318,7 @@ function isConfigured() {
|
|
|
3225
3318
|
function reset() {
|
|
3226
3319
|
configured = null;
|
|
3227
3320
|
}
|
|
3228
|
-
const GuideAI = { configure, identify, setUserProfile, isConfigured, reset };
|
|
3321
|
+
const GuideAI = { configure, identify, setUserProfile, setToolContext, isConfigured, reset };
|
|
3229
3322
|
const AUDIO_TYPES = {
|
|
3230
3323
|
m4a: "audio/m4a",
|
|
3231
3324
|
mp4: "audio/mp4",
|
|
@@ -3496,4 +3589,4 @@ export {
|
|
|
3496
3589
|
requireConfigured as r,
|
|
3497
3590
|
useGuideAIRuntime as u
|
|
3498
3591
|
};
|
|
3499
|
-
//# sourceMappingURL=useOnboarding-
|
|
3592
|
+
//# sourceMappingURL=useOnboarding-DAEGoYSs.js.map
|