@guuey/chat 0.16.17 → 0.16.22
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/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/oauth.d.ts +63 -0
- package/dist/oauth.d.ts.map +1 -1
- package/dist/oauth.js +56 -1
- package/dist/plan.d.ts.map +1 -1
- package/dist/plan.js +6 -1
- package/dist/react/components.d.ts.map +1 -1
- package/dist/react/components.js +5 -1
- package/dist/react/guuey-chat.d.ts +6 -0
- package/dist/react/guuey-chat.d.ts.map +1 -1
- package/dist/react/guuey-chat.js +24 -5
- package/dist/strings.d.ts +10 -0
- package/dist/strings.d.ts.map +1 -1
- package/dist/strings.js +3 -0
- package/dist/types.d.ts +14 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/corpus/__snapshots__/corpus.test.ts.snap +24 -0
- package/src/index.ts +4 -0
- package/src/oauth.ts +94 -1
- package/src/plan.ts +8 -1
- package/src/react/components.tsx +11 -1
- package/src/react/guuey-chat.tsx +36 -5
- package/src/strings.ts +15 -0
- package/src/types.ts +14 -2
package/dist/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export { calmPolicy, type TranscriptPolicyOverrides, debugPolicy, type Transcrip
|
|
|
15
15
|
export { defaultChatStrings, humanizeToolName, type ChatStrings, } from "./strings.js";
|
|
16
16
|
export { transcriptInputsFromHistory } from "./history-inputs.js";
|
|
17
17
|
export { buildHitlAnswer, grantModeDisplay, hitlPromptsFromFold, type HitlAnswerRecord, type HitlPromptAction, } from "./hitl.js";
|
|
18
|
-
export { OAUTH_LINK_PARAMS, OAUTH_RETURN_PARAMS, OAUTH_SCHEME, oauthAuthorizeAsk, oauthAuthorizeHref, parseOAuthReturn, stripOAuthReturn, type OAuthAuthorizeAsk, type OAuthReturn, } from "./oauth.js";
|
|
18
|
+
export { OAUTH_LINK_PARAMS, OAUTH_RETURN_PARAMS, OAUTH_SCHEME, OAUTH_UPFRONT_METADATA, authRequiredFromAsks, oauthAuthorizeAsk, oauthAuthorizeHref, parseOAuthReturn, stripOAuthReturn, type AuthRequired, type AuthRequiredServer, type OAuthAuthorizeAsk, type OAuthReturn, } from "./oauth.js";
|
|
19
19
|
export { DEFAULT_CHAT_THEME, GUUEY_CHAT_THEME, GuueyChatAccentRamp, GuueyChatErrorRamp, GuueyChatPalette, GuueyChatRamps, GuueyChatRampSet, GuueyChatTheme, GuueyChatToneRamp, resolveTheme, resolveCourtTheme, } from "./theme.js";
|
|
20
20
|
export type { ChatDebugEvent, CitationsItem, CodeItem, CompactionItem, DataResultItem, DisplayItem, ErrorItem, HistoryBoundaryItem, ItemKey, HitlPromptInput, HitlPromptItem, MediaItem, NoticeItem, ProfilePromptInput, ProfilePromptItem, PromptItem, PromptItemInput, ReasoningItem, StatusLineItem, TextItem, ToolGroupItem, ToolItem, TranscriptInputs, TranscriptMessage, TranscriptOverrides, TranscriptPlan, PlanViewSummary, UnknownItem, UserMessageItem, ViewMountItem, ViewRefItem, } from "./types.js";
|
|
21
21
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EACL,aAAa,EACb,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,UAAU,EACV,KAAK,yBAAyB,EAC9B,WAAW,EACX,KAAK,gBAAgB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,KAAK,WAAW,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACtB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,cAAc,EACd,aAAa,EACb,QAAQ,EACR,cAAc,EACd,cAAc,EACd,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,OAAO,EACP,eAAe,EACf,cAAc,EACd,SAAS,EACT,UAAU,EACV,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,aAAa,EACb,cAAc,EACd,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,WAAW,EACX,eAAe,EACf,aAAa,EACb,WAAW,GACZ,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EACL,aAAa,EACb,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,UAAU,EACV,KAAK,yBAAyB,EAC9B,WAAW,EACX,KAAK,gBAAgB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,KAAK,WAAW,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACtB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,cAAc,EACd,aAAa,EACb,QAAQ,EACR,cAAc,EACd,cAAc,EACd,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,OAAO,EACP,eAAe,EACf,cAAc,EACd,SAAS,EACT,UAAU,EACV,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,aAAa,EACb,cAAc,EACd,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,WAAW,EACX,eAAe,EACf,aAAa,EACb,WAAW,GACZ,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -15,5 +15,5 @@ export { calmPolicy, debugPolicy, } from "./policy.js";
|
|
|
15
15
|
export { defaultChatStrings, humanizeToolName, } from "./strings.js";
|
|
16
16
|
export { transcriptInputsFromHistory } from "./history-inputs.js";
|
|
17
17
|
export { buildHitlAnswer, grantModeDisplay, hitlPromptsFromFold, } from "./hitl.js";
|
|
18
|
-
export { OAUTH_LINK_PARAMS, OAUTH_RETURN_PARAMS, OAUTH_SCHEME, oauthAuthorizeAsk, oauthAuthorizeHref, parseOAuthReturn, stripOAuthReturn, } from "./oauth.js";
|
|
18
|
+
export { OAUTH_LINK_PARAMS, OAUTH_RETURN_PARAMS, OAUTH_SCHEME, OAUTH_UPFRONT_METADATA, authRequiredFromAsks, oauthAuthorizeAsk, oauthAuthorizeHref, parseOAuthReturn, stripOAuthReturn, } from "./oauth.js";
|
|
19
19
|
export { DEFAULT_CHAT_THEME, GUUEY_CHAT_THEME, GuueyChatAccentRamp, GuueyChatErrorRamp, GuueyChatPalette, GuueyChatRamps, GuueyChatRampSet, GuueyChatTheme, GuueyChatToneRamp, resolveTheme, resolveCourtTheme, } from "./theme.js";
|
package/dist/oauth.d.ts
CHANGED
|
@@ -17,6 +17,15 @@
|
|
|
17
17
|
* `?error=<reason>` on failure). The broker allowlists it; the client
|
|
18
18
|
* just says where it lives.
|
|
19
19
|
*
|
|
20
|
+
* ## Required before use (guuey#605)
|
|
21
|
+
*
|
|
22
|
+
* An ask whose `metadata.authMode` is `"upfront"` is not an aside: the
|
|
23
|
+
* runtime REFUSED the turn on it (no model call, no agent answer) and will
|
|
24
|
+
* refuse every turn until the account is connected. {@link authRequiredFromAsks}
|
|
25
|
+
* lifts that off a turn's pending asks as {@link AuthRequired}, naming the
|
|
26
|
+
* servers, so a surface renders the connect step FIRST and stops inviting
|
|
27
|
+
* messages that cannot be answered.
|
|
28
|
+
*
|
|
20
29
|
* On return the surface strips the two params, shows a one-line notice, and
|
|
21
30
|
* does nothing else: the NEXT turn's pre-turn preflight on the pod resolves
|
|
22
31
|
* `connected` (or asks again). No client-side state survives the redirect
|
|
@@ -39,10 +48,34 @@ export declare const OAUTH_RETURN_PARAMS: {
|
|
|
39
48
|
readonly connected: "connected";
|
|
40
49
|
readonly error: "error";
|
|
41
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* The producer's ask-metadata contract for guuey#605 (`authMode:'upfront'` —
|
|
53
|
+
* require sign-in BEFORE use). SYNC with the runtime's
|
|
54
|
+
* `mcp-oauth-consent.ts#MCP_OAUTH_METADATA_AUTH_MODE`; the corpus fixture
|
|
55
|
+
* pins the pair. An ON-DEMAND ask carries none of these keys, so a lazy
|
|
56
|
+
* stream stays byte-identical to its pre-#605 shape.
|
|
57
|
+
*/
|
|
58
|
+
export declare const OAUTH_UPFRONT_METADATA: {
|
|
59
|
+
/** Carries `"upfront"`, and only that. */
|
|
60
|
+
readonly authMode: "authMode";
|
|
61
|
+
/** The value the key ever carries. */
|
|
62
|
+
readonly upfront: "upfront";
|
|
63
|
+
/** The server's human label, when the authorization server supplied one. */
|
|
64
|
+
readonly displayName: "displayName";
|
|
65
|
+
/** The declared `mcpServers` key — the server's identity in every surface. */
|
|
66
|
+
readonly serverName: "serverName";
|
|
67
|
+
};
|
|
42
68
|
/** What an auth ask declares once narrowed to the OAuth arm. */
|
|
43
69
|
export interface OAuthAuthorizeAsk {
|
|
44
70
|
authorizationUrl: string;
|
|
45
71
|
scopes: readonly string[];
|
|
72
|
+
/**
|
|
73
|
+
* guuey#605 — this connection is REQUIRED BEFORE USE: the runtime refused
|
|
74
|
+
* the turn (no model call, no agent answer) and will keep refusing until
|
|
75
|
+
* the account is connected. Surfaces frame the card as the connect step
|
|
76
|
+
* rather than an aside. `false` = today's on-demand ask.
|
|
77
|
+
*/
|
|
78
|
+
upfront: boolean;
|
|
46
79
|
}
|
|
47
80
|
/**
|
|
48
81
|
* Narrow an ask to the OAuth arm: `kind:"auth"` + `authConfig.scheme ===
|
|
@@ -51,6 +84,36 @@ export interface OAuthAuthorizeAsk {
|
|
|
51
84
|
* `null` and renders as an ordinary hitl card.
|
|
52
85
|
*/
|
|
53
86
|
export declare function oauthAuthorizeAsk(ask: AgPausedAsk): OAuthAuthorizeAsk | null;
|
|
87
|
+
/** One server the user must connect before the agent will answer. */
|
|
88
|
+
export interface AuthRequiredServer {
|
|
89
|
+
/** The declared `mcpServers` key; the askId's own suffix when the ask carries no metadata. */
|
|
90
|
+
serverName: string;
|
|
91
|
+
/** What to call it in copy — the authorization server's label, else `serverName`. */
|
|
92
|
+
label: string;
|
|
93
|
+
/** The ask to render as the connect step (its `authorizationUrl` is the door). */
|
|
94
|
+
ask: AgPausedAsk;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The typed refusal (guuey#605): the runtime would not run this agent
|
|
98
|
+
* because one or more `authMode:'upfront'` OAuth servers have no live
|
|
99
|
+
* connection for this end user. Derived from the PENDING asks of the
|
|
100
|
+
* transcript — a settled or dismissed ask never gates a surface (a "no"
|
|
101
|
+
* must not brick the chat; the pod simply re-cards on the next turn).
|
|
102
|
+
*/
|
|
103
|
+
export interface AuthRequired {
|
|
104
|
+
servers: readonly AuthRequiredServer[];
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Read {@link AuthRequired} off a turn's asks. `null` when nothing upfront
|
|
108
|
+
* is pending — the ONLY signal a surface should gate its composer on.
|
|
109
|
+
*
|
|
110
|
+
* Pass just the asks still awaiting an answer: a resolved / declined /
|
|
111
|
+
* dismissed record must not hold the door shut, because the client is not
|
|
112
|
+
* the enforcer here. The POD is: it refuses each turn while the connection
|
|
113
|
+
* is missing and re-emits the card. This derivation exists so a surface can
|
|
114
|
+
* say so before the user spends a turn finding out.
|
|
115
|
+
*/
|
|
116
|
+
export declare function authRequiredFromAsks(asks: readonly AgPausedAsk[]): AuthRequired | null;
|
|
54
117
|
/**
|
|
55
118
|
* The link to open for a mode pick: `authorizationUrl` + `&mode=<grantModeId>`
|
|
56
119
|
* + `&returnTo=<returnTo>` (each value URI-encoded; `?` vs `&` chosen from
|
package/dist/oauth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,mFAAmF;AACnF,eAAO,MAAM,YAAY,WAAW,CAAC;AAErC,kEAAkE;AAClE,eAAO,MAAM,iBAAiB;;;CAAkD,CAAC;AAEjF,oEAAoE;AACpE,eAAO,MAAM,mBAAmB;;;CAAsD,CAAC;AAEvF;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB;IACjC,0CAA0C;;IAE1C,sCAAsC;;IAEtC,4EAA4E;;IAE5E,8EAA8E;;CAEtE,CAAC;AAEX,gEAAgE;AAChE,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B;;;;;OAKG;IACH,OAAO,EAAE,OAAO,CAAC;CAClB;AAQD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,WAAW,GAAG,iBAAiB,GAAG,IAAI,CAS5E;AAED,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,8FAA8F;IAC9F,UAAU,EAAE,MAAM,CAAC;IACnB,qFAAqF;IACrF,KAAK,EAAE,MAAM,CAAC;IACd,kFAAkF;IAClF,GAAG,EAAE,WAAW,CAAC;CAClB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACxC;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,GAAG,YAAY,GAAG,IAAI,CAgBtF;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAczG;AAED,2DAA2D;AAC3D,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AA4BtC;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAUvE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAiBpD"}
|
package/dist/oauth.js
CHANGED
|
@@ -4,6 +4,28 @@ export const OAUTH_SCHEME = "oauth2";
|
|
|
4
4
|
export const OAUTH_LINK_PARAMS = { mode: "mode", returnTo: "returnTo" };
|
|
5
5
|
/** The query params the broker's callback appends to `returnTo`. */
|
|
6
6
|
export const OAUTH_RETURN_PARAMS = { connected: "connected", error: "error" };
|
|
7
|
+
/**
|
|
8
|
+
* The producer's ask-metadata contract for guuey#605 (`authMode:'upfront'` —
|
|
9
|
+
* require sign-in BEFORE use). SYNC with the runtime's
|
|
10
|
+
* `mcp-oauth-consent.ts#MCP_OAUTH_METADATA_AUTH_MODE`; the corpus fixture
|
|
11
|
+
* pins the pair. An ON-DEMAND ask carries none of these keys, so a lazy
|
|
12
|
+
* stream stays byte-identical to its pre-#605 shape.
|
|
13
|
+
*/
|
|
14
|
+
export const OAUTH_UPFRONT_METADATA = {
|
|
15
|
+
/** Carries `"upfront"`, and only that. */
|
|
16
|
+
authMode: "authMode",
|
|
17
|
+
/** The value the key ever carries. */
|
|
18
|
+
upfront: "upfront",
|
|
19
|
+
/** The server's human label, when the authorization server supplied one. */
|
|
20
|
+
displayName: "displayName",
|
|
21
|
+
/** The declared `mcpServers` key — the server's identity in every surface. */
|
|
22
|
+
serverName: "serverName",
|
|
23
|
+
};
|
|
24
|
+
/** Read one string off an ask's metadata; `null` for absent or non-string. */
|
|
25
|
+
function metadataString(ask, key) {
|
|
26
|
+
const value = ask.metadata?.[key];
|
|
27
|
+
return typeof value === "string" && value !== "" ? value : null;
|
|
28
|
+
}
|
|
7
29
|
/**
|
|
8
30
|
* Narrow an ask to the OAuth arm: `kind:"auth"` + `authConfig.scheme ===
|
|
9
31
|
* "oauth2"` + an `authorizationUrl` to open. Anything else (a plain
|
|
@@ -16,7 +38,40 @@ export function oauthAuthorizeAsk(ask) {
|
|
|
16
38
|
const { scheme, authorizationUrl, scopes } = ask.authConfig;
|
|
17
39
|
if (scheme !== OAUTH_SCHEME || authorizationUrl === undefined || authorizationUrl === "")
|
|
18
40
|
return null;
|
|
19
|
-
return {
|
|
41
|
+
return {
|
|
42
|
+
authorizationUrl,
|
|
43
|
+
scopes: scopes ?? [],
|
|
44
|
+
upfront: metadataString(ask, OAUTH_UPFRONT_METADATA.authMode) === OAUTH_UPFRONT_METADATA.upfront,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Read {@link AuthRequired} off a turn's asks. `null` when nothing upfront
|
|
49
|
+
* is pending — the ONLY signal a surface should gate its composer on.
|
|
50
|
+
*
|
|
51
|
+
* Pass just the asks still awaiting an answer: a resolved / declined /
|
|
52
|
+
* dismissed record must not hold the door shut, because the client is not
|
|
53
|
+
* the enforcer here. The POD is: it refuses each turn while the connection
|
|
54
|
+
* is missing and re-emits the card. This derivation exists so a surface can
|
|
55
|
+
* say so before the user spends a turn finding out.
|
|
56
|
+
*/
|
|
57
|
+
export function authRequiredFromAsks(asks) {
|
|
58
|
+
const servers = [];
|
|
59
|
+
const seen = new Set();
|
|
60
|
+
for (const ask of asks) {
|
|
61
|
+
const oauth = oauthAuthorizeAsk(ask);
|
|
62
|
+
if (oauth === null || !oauth.upfront)
|
|
63
|
+
continue;
|
|
64
|
+
const serverName = metadataString(ask, OAUTH_UPFRONT_METADATA.serverName) ?? ask.askId;
|
|
65
|
+
if (seen.has(serverName))
|
|
66
|
+
continue;
|
|
67
|
+
seen.add(serverName);
|
|
68
|
+
servers.push({
|
|
69
|
+
serverName,
|
|
70
|
+
label: metadataString(ask, OAUTH_UPFRONT_METADATA.displayName) ?? serverName,
|
|
71
|
+
ask,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return servers.length === 0 ? null : { servers };
|
|
20
75
|
}
|
|
21
76
|
/**
|
|
22
77
|
* The link to open for a mode pick: `authorizationUrl` + `&mode=<grantModeId>`
|
package/dist/plan.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"AAkCA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD,OAAO,KAAK,EAUV,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EAIf,MAAM,YAAY,CAAC;AAuqBpB,uCAAuC;AACvC,wBAAgB,cAAc,CAC5B,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,gBAAgB,EACxB,SAAS,GAAE,mBAAwB,GAClC,cAAc,
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"AAkCA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD,OAAO,KAAK,EAUV,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EAIf,MAAM,YAAY,CAAC;AAuqBpB,uCAAuC;AACvC,wBAAgB,cAAc,CAC5B,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,gBAAgB,EACxB,SAAS,GAAE,mBAAwB,GAClC,cAAc,CAyXhB;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,cAAc,CAAC,GACxD;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,GAAG,SAAS,CAiB5D"}
|
package/dist/plan.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { snapshotViewMount, toolResultLocator, toolResultViewMount, uiResourceChannel, } from "@guuey/mcp-apps-host";
|
|
2
2
|
import { grantModeDisplay } from "./hitl.js";
|
|
3
|
-
import { oauthAuthorizeAsk } from "./oauth.js";
|
|
3
|
+
import { authRequiredFromAsks, oauthAuthorizeAsk } from "./oauth.js";
|
|
4
4
|
/** R5's giant threshold: above this byte count the state is `giant`. */
|
|
5
5
|
const GIANT_RESULT_BYTES = 16_384;
|
|
6
6
|
/** Approximate byte size of a JSON value — deterministic, allocation-bounded. */
|
|
@@ -981,6 +981,11 @@ export function planTranscript(inputs, policy, overrides = {}) {
|
|
|
981
981
|
status: deriveStatus(inputs, policy),
|
|
982
982
|
recovery: inputs.adopted === true && policy.debugDetail ? policy.strings.recoveredFromHistory : null,
|
|
983
983
|
views,
|
|
984
|
+
// guuey#605 — the typed refusal, derived from the PENDING hitl asks only.
|
|
985
|
+
// A settled or dismissed record never gates the surface: the pod is the
|
|
986
|
+
// enforcer (it refuses each turn and re-cards), and a "no" that locked the
|
|
987
|
+
// composer would dead-end a user who cannot un-dismiss.
|
|
988
|
+
authRequired: authRequiredFromAsks(inputs.prompts.flatMap((p) => (p.kind === "hitl" && p.state === "pending" ? [p.ask] : []))),
|
|
984
989
|
};
|
|
985
990
|
}
|
|
986
991
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/react/components.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/react/components.tsx"],"names":[],"mappings":"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"}
|
package/dist/react/components.js
CHANGED
|
@@ -199,7 +199,11 @@ export function DefaultPrompt({ item, ctx }) {
|
|
|
199
199
|
: s.promptDeclinedRecord }));
|
|
200
200
|
}
|
|
201
201
|
const answerable = item.state === "pending" || (item.state === "cancelled" && item.expanded);
|
|
202
|
-
|
|
202
|
+
// guuey#605 — a REQUIRED connection is a step, not an aside: the runtime
|
|
203
|
+
// refused this turn on it and answers nothing until it is connected. The
|
|
204
|
+
// card says so above the ask, and carries a class a theme can lift.
|
|
205
|
+
const requiredConnection = item.oauth?.upfront === true;
|
|
206
|
+
return (_jsxs("div", { className: `guuey-chat-prompt${requiredConnection ? " guuey-chat-prompt-required" : ""}`, role: "group", children: [item.state === "cancelled" && (_jsx("button", { type: "button", className: "guuey-chat-prompt-record guuey-chat-prompt-cancelled", "aria-expanded": item.expanded, onClick: () => ctx.onToggle(item.key), children: s.promptDismissed })), answerable && (_jsxs(_Fragment, { children: [requiredConnection && (_jsx("p", { className: "guuey-chat-prompt-required-hint", children: s.authRequiredHint })), item.message !== null && _jsx("p", { className: "guuey-chat-prompt-ask", children: item.message }), _jsxs("div", { className: "guuey-chat-prompt-actions", children: [item.grantModes.length === 0 ? (_jsx("button", { ref: firstAction, type: "button", className: "guuey-chat-prompt-accept", onClick: () => ctx.onPromptAction?.(item, "accept"), children: s.promptAccept })) : (item.grantModes.map((mode, i) => (_jsx("button", { ref: i === 0 ? firstAction : undefined, type: "button", className: "guuey-chat-prompt-accept", title: mode.description, onClick: () => ctx.onPromptAction?.(item, { grantModeId: mode.id }), children: mode.label ?? mode.id }, mode.id)))), item.oauth !== null ? (_jsx("button", { type: "button", onClick: () => ctx.onPromptAction?.(item, "dismiss"), children: s.promptNotNow })) : (_jsx("button", { type: "button", onClick: () => ctx.onPromptAction?.(item, "decline"), children: s.promptDecline }))] })] }))] }));
|
|
203
207
|
}
|
|
204
208
|
if (item.state !== "pending") {
|
|
205
209
|
return (_jsxs("p", { className: `guuey-chat-prompt-record guuey-chat-prompt-${item.state}`, children: [item.promptKind, ": ", item.state] }));
|
|
@@ -24,6 +24,12 @@
|
|
|
24
24
|
* (partial text kept, "Stopped." marked — the hook's contract).
|
|
25
25
|
* - Enter sends; Shift+Enter inserts a newline; an IME-composing Enter
|
|
26
26
|
* never sends (the candidate commit is not a submit).
|
|
27
|
+
* - `plan.authRequired !== null` (guuey#605 — an `authMode:'upfront'` OAuth
|
|
28
|
+
* server is pending connection) → input disabled, `composerAuthRequired`
|
|
29
|
+
* placeholder, Send gated, and a connect-first line above the composer.
|
|
30
|
+
* The RUNTIME is the enforcer (it refuses every turn before any model
|
|
31
|
+
* call); this only stops the user spending a message to learn that.
|
|
32
|
+
* Dismissing the card releases the gate — no dead end.
|
|
27
33
|
*
|
|
28
34
|
* ## History
|
|
29
35
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guuey-chat.d.ts","sourceRoot":"","sources":["../../src/react/guuey-chat.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"guuey-chat.d.ts","sourceRoot":"","sources":["../../src/react/guuey-chat.tsx"],"names":[],"mappings":"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"}
|
package/dist/react/guuey-chat.js
CHANGED
|
@@ -25,6 +25,12 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
25
25
|
* (partial text kept, "Stopped." marked — the hook's contract).
|
|
26
26
|
* - Enter sends; Shift+Enter inserts a newline; an IME-composing Enter
|
|
27
27
|
* never sends (the candidate commit is not a submit).
|
|
28
|
+
* - `plan.authRequired !== null` (guuey#605 — an `authMode:'upfront'` OAuth
|
|
29
|
+
* server is pending connection) → input disabled, `composerAuthRequired`
|
|
30
|
+
* placeholder, Send gated, and a connect-first line above the composer.
|
|
31
|
+
* The RUNTIME is the enforcer (it refuses every turn before any model
|
|
32
|
+
* call); this only stops the user spending a message to learn that.
|
|
33
|
+
* Dismissing the card releases the gate — no dead end.
|
|
28
34
|
*
|
|
29
35
|
* ## History
|
|
30
36
|
*
|
|
@@ -230,8 +236,15 @@ export const GuueyChat = forwardRef(function GuueyChat(props, ref) {
|
|
|
230
236
|
// when several chats mount on one page — a static id would collide.
|
|
231
237
|
const composerId = useId();
|
|
232
238
|
const busy = invoke.status !== "ready";
|
|
239
|
+
// guuey#605 — the connect-first gate. While an `authMode:'upfront'` OAuth
|
|
240
|
+
// server is pending connection the RUNTIME refuses every turn before any
|
|
241
|
+
// model call, so inviting a message here would only spend one to be told
|
|
242
|
+
// the same thing. The gate is the plan's typed refusal, and it releases the
|
|
243
|
+
// moment the card is dismissed or answered (the pod re-cards next turn) —
|
|
244
|
+
// the client never claims more than the pod enforces, and no one dead-ends.
|
|
245
|
+
const authRequired = plan.authRequired;
|
|
233
246
|
const available = endpointUrl !== null;
|
|
234
|
-
const canSend = available && !busy && input.trim() !== "";
|
|
247
|
+
const canSend = available && !busy && authRequired === null && input.trim() !== "";
|
|
235
248
|
// ── The imperative seam (guuey#210) ──────────────────────────────────
|
|
236
249
|
// ONE stable handle for the component's whole life (hosts capture it in
|
|
237
250
|
// `onReady` and keep it), reading live truth through a ref so a call
|
|
@@ -533,13 +546,15 @@ export const GuueyChat = forwardRef(function GuueyChat(props, ref) {
|
|
|
533
546
|
}, [handle]);
|
|
534
547
|
const submit = useCallback(() => {
|
|
535
548
|
const text = input.trim();
|
|
536
|
-
|
|
549
|
+
// guuey#605: the connect-first gate belongs on the SEND path too, not
|
|
550
|
+
// just the disabled attribute — an Enter keypress reaches here directly.
|
|
551
|
+
if (text === "" || !available || busy || authRequired !== null)
|
|
537
552
|
return;
|
|
538
553
|
setInput("");
|
|
539
554
|
void invoke.send(text).catch(() => {
|
|
540
555
|
// The hook surfaces the failure (`error` / R0 failed-send).
|
|
541
556
|
});
|
|
542
|
-
}, [input, available, busy, invoke]);
|
|
557
|
+
}, [input, available, busy, authRequired, invoke]);
|
|
543
558
|
const handleRetry = useCallback((item) => {
|
|
544
559
|
void invoke.send(item.text).catch(() => {
|
|
545
560
|
// Same contract as submit: the hook owns failure surfacing.
|
|
@@ -584,7 +599,7 @@ export const GuueyChat = forwardRef(function GuueyChat(props, ref) {
|
|
|
584
599
|
}
|
|
585
600
|
}, children: clearArmed ? strings.clearConversationConfirm : strings.clearConversationLabel }) })), pendingLink !== null && (_jsxs("div", { role: "status", className: "guuey-chat-link-ask", children: [_jsx("span", { className: "guuey-chat-link-ask-label", children: strings.linkAskLabel(new URL(pendingLink).host) }), _jsx("span", { className: "guuey-chat-link-ask-url", children: pendingLink }), _jsx("a", { className: "guuey-chat-link-ask-open", href: pendingLink, target: "_blank", rel: "noopener noreferrer", onClick: () => setPendingLink(null), children: strings.linkOpen }), _jsx("button", { type: "button", className: "guuey-chat-link-ask-dismiss", onClick: () => setPendingLink(null), children: strings.linkDismiss })] })), oauthReturn.notice !== null && (_jsxs("p", { role: "status", className: `guuey-chat-oauth-notice guuey-chat-oauth-${oauthReturn.notice.kind}`, children: [oauthReturn.notice.kind === "connected"
|
|
586
601
|
? strings.oauthConnected(oauthReturn.notice.serverName)
|
|
587
|
-
: strings.oauthFailed(oauthReturn.notice.reason), _jsx("button", { type: "button", className: "guuey-chat-oauth-dismiss", onClick: oauthReturn.dismiss, children: strings.promptDismissed })] })), composer && (_jsxs("form", { className: "guuey-chat-composer", onSubmit: (e) => {
|
|
602
|
+
: strings.oauthFailed(oauthReturn.notice.reason), _jsx("button", { type: "button", className: "guuey-chat-oauth-dismiss", onClick: oauthReturn.dismiss, children: strings.promptDismissed })] })), authRequired !== null && (_jsxs("p", { role: "status", className: "guuey-chat-auth-required", children: [_jsx("strong", { className: "guuey-chat-auth-required-heading", children: strings.authRequiredHeading(authRequired.servers.map((s) => s.label).join(", ")) }), _jsx("span", { className: "guuey-chat-auth-required-hint", children: strings.authRequiredHint })] })), composer && (_jsxs("form", { className: "guuey-chat-composer", onSubmit: (e) => {
|
|
588
603
|
e.preventDefault();
|
|
589
604
|
submit();
|
|
590
605
|
}, children: [_jsx("textarea", { ref: inputRef, id: composerId, name: "message", className: "guuey-chat-composer-input", rows: 1, value: input, onChange: (e) => setInput(e.target.value), onKeyDown: (e) => {
|
|
@@ -594,5 +609,9 @@ export const GuueyChat = forwardRef(function GuueyChat(props, ref) {
|
|
|
594
609
|
e.preventDefault();
|
|
595
610
|
submit();
|
|
596
611
|
}
|
|
597
|
-
}, disabled: !available, "aria-label": strings.composerLabel, placeholder: available
|
|
612
|
+
}, disabled: !available || authRequired !== null, "aria-label": strings.composerLabel, placeholder: !available
|
|
613
|
+
? strings.composerUnavailable
|
|
614
|
+
: authRequired !== null
|
|
615
|
+
? strings.composerAuthRequired
|
|
616
|
+
: strings.composerPlaceholder }), busy ? (_jsx("button", { type: "button", className: "guuey-chat-composer-stop", onClick: () => invoke.abort(), children: strings.stop })) : (_jsx("button", { type: "submit", className: "guuey-chat-composer-send", disabled: !canSend, children: strings.send }))] }))] }));
|
|
598
617
|
});
|
package/dist/strings.d.ts
CHANGED
|
@@ -111,6 +111,16 @@ export interface ChatStrings {
|
|
|
111
111
|
promptOAuthSent: (modeLabel: string) => string;
|
|
112
112
|
oauthConnected: (serverName: string) => string;
|
|
113
113
|
oauthFailed: (reason: string) => string;
|
|
114
|
+
/**
|
|
115
|
+
* The `authMode:'upfront'` connect-first framing (guuey#605): the agent
|
|
116
|
+
* cannot answer at all until these accounts are connected, so the card
|
|
117
|
+
* reads as a step and the composer says why it is holding.
|
|
118
|
+
* `authRequiredHeading` takes the servers' labels already joined for
|
|
119
|
+
* display; `composerAuthRequired` is the held composer's placeholder.
|
|
120
|
+
*/
|
|
121
|
+
authRequiredHeading: (serverLabels: string) => string;
|
|
122
|
+
authRequiredHint: string;
|
|
123
|
+
composerAuthRequired: string;
|
|
114
124
|
/** R16 — the notice row's label (provenance shows only under debug). */
|
|
115
125
|
noticeLabel: string;
|
|
116
126
|
/**
|
package/dist/strings.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../src/strings.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../src/strings.ts"],"names":[],"mappings":"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"}
|
package/dist/strings.js
CHANGED
|
@@ -76,6 +76,9 @@ export const defaultChatStrings = {
|
|
|
76
76
|
promptOAuthSent: (modeLabel) => `Connecting — ${modeLabel}`,
|
|
77
77
|
oauthConnected: (serverName) => `Connected ${serverName}. The agent can use it from your next message.`,
|
|
78
78
|
oauthFailed: (reason) => `Couldn't connect: ${reason}`,
|
|
79
|
+
authRequiredHeading: (serverLabels) => `Connect ${serverLabels} to start`,
|
|
80
|
+
authRequiredHint: "This agent needs the account before it can answer.",
|
|
81
|
+
composerAuthRequired: "Connect the account above to start.",
|
|
79
82
|
noticeLabel: "Note",
|
|
80
83
|
linkAskLabel: (host) => `This card wants to open ${host}`,
|
|
81
84
|
linkOpen: "Open",
|
package/dist/types.d.ts
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import type { AgGrantMode, AgNoticeSource, AgPausedAsk, AgReduceResult, AgSource, JsonValue } from "@silverprotocol/core";
|
|
15
15
|
import type { AgentInvokeStatus, HistoryCard } from "@guuey/agent-client";
|
|
16
16
|
import type { ViewCspDiagnosis, ViewHostPhase, ViewMount, ViewMountChannel } from "@guuey/mcp-apps-host";
|
|
17
|
+
import type { AuthRequired, OAuthAuthorizeAsk } from "./oauth.js";
|
|
17
18
|
/**
|
|
18
19
|
* One settled entry of the flat conversation transcript — structurally
|
|
19
20
|
* compatible with the hook's `AgentMessage`, plus the optional
|
|
@@ -368,12 +369,11 @@ export interface HitlPromptItem extends BaseItem {
|
|
|
368
369
|
* `authConfig.scheme:"oauth2"` + an `authorizationUrl`. There is no
|
|
369
370
|
* answer door for this ask — a mode pick OPENS `authorizationUrl` with
|
|
370
371
|
* `&mode=` + `&returnTo=` appended (`oauthAuthorizeHref`); "Not now" is a
|
|
371
|
-
* plain dismissal. `null` for every other ask.
|
|
372
|
+
* plain dismissal. `null` for every other ask. `upfront` (guuey#605) marks
|
|
373
|
+
* a connection REQUIRED BEFORE USE — the turn carrying this ask was
|
|
374
|
+
* refused, not answered.
|
|
372
375
|
*/
|
|
373
|
-
oauth:
|
|
374
|
-
authorizationUrl: string;
|
|
375
|
-
scopes: readonly string[];
|
|
376
|
-
} | null;
|
|
376
|
+
oauth: OAuthAuthorizeAsk | null;
|
|
377
377
|
state: "pending" | "resolved" | "declined" | "cancelled";
|
|
378
378
|
/** Echo of the chosen mode id (identity, never displayed as meaning). */
|
|
379
379
|
chosenModeId: string | null;
|
|
@@ -553,6 +553,15 @@ export interface TranscriptPlan {
|
|
|
553
553
|
* mount even when the transcript shows only chips.
|
|
554
554
|
*/
|
|
555
555
|
views: PlanViewSummary[];
|
|
556
|
+
/**
|
|
557
|
+
* guuey#605 — the typed refusal: non-null while one or more
|
|
558
|
+
* `authMode:'upfront'` OAuth servers are PENDING connection, naming them.
|
|
559
|
+
* The runtime refuses every turn (no model call) until they are connected,
|
|
560
|
+
* so a surface renders the connect step first and holds its composer; a
|
|
561
|
+
* dismissed card releases the gate (the pod re-cards next turn — a "no"
|
|
562
|
+
* never bricks the chat). `null` on every ordinary plan.
|
|
563
|
+
*/
|
|
564
|
+
authRequired: AuthRequired | null;
|
|
556
565
|
}
|
|
557
566
|
export {};
|
|
558
567
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,WAAW,EACX,cAAc,EACd,QAAQ,EACR,SAAS,EACV,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,SAAS,EACT,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@guuey/chat",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.22",
|
|
4
4
|
"description": "The default end-user transcript UI for guuey agents — the headless view-model (planTranscript), calm/debug presets, the GuueyChatTheme token schema, the ChatStrings i18n seam, and (at ./react) the component kit that renders it: per-category components, <Transcript>, the live + history input assemblers, and stick-to-bottom/windowed/accessible transcript behavior; at ./native, the React Native renderer over the same view-model.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"@silverprotocol/core": "0.5.4",
|
|
40
40
|
"@silverprotocol/richtext": "0.5.4",
|
|
41
41
|
"zod": "^4.3.6",
|
|
42
|
-
"@guuey/
|
|
43
|
-
"@guuey/
|
|
42
|
+
"@guuey/agent-client": "0.16.22",
|
|
43
|
+
"@guuey/mcp-apps-host": "0.16.22"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"react": ">=18",
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`corpus > 1. forty-tools — grouping caps the rows; plan stays O(groups); keys stable 1`] = `
|
|
4
4
|
{
|
|
5
|
+
"authRequired": null,
|
|
5
6
|
"items": [
|
|
6
7
|
{
|
|
7
8
|
"directive": false,
|
|
@@ -840,6 +841,7 @@ exports[`corpus > 1. forty-tools — grouping caps the rows; plan stays O(groups
|
|
|
840
841
|
|
|
841
842
|
exports[`corpus > 2. midstream-tool-failure — failed inline; badge without unroll 1`] = `
|
|
842
843
|
{
|
|
844
|
+
"authRequired": null,
|
|
843
845
|
"items": [
|
|
844
846
|
{
|
|
845
847
|
"directive": false,
|
|
@@ -978,6 +980,7 @@ exports[`corpus > 2. midstream-tool-failure — failed inline; badge without unr
|
|
|
978
980
|
|
|
979
981
|
exports[`corpus > 3. cold-start — R12 escalation at 0 / 2.5 s / 15 s 1`] = `
|
|
980
982
|
{
|
|
983
|
+
"authRequired": null,
|
|
981
984
|
"items": [
|
|
982
985
|
{
|
|
983
986
|
"directive": false,
|
|
@@ -1003,6 +1006,7 @@ exports[`corpus > 3. cold-start — R12 escalation at 0 / 2.5 s / 15 s 1`] = `
|
|
|
1003
1006
|
|
|
1004
1007
|
exports[`corpus > 4. consent-gate — pending grant-mode card → answered one-line collapse (guuey#207 hitl arm) 1`] = `
|
|
1005
1008
|
{
|
|
1009
|
+
"authRequired": null,
|
|
1006
1010
|
"items": [
|
|
1007
1011
|
{
|
|
1008
1012
|
"directive": false,
|
|
@@ -1078,6 +1082,7 @@ exports[`corpus > 4. consent-gate — pending grant-mode card → answered one-l
|
|
|
1078
1082
|
|
|
1079
1083
|
exports[`corpus > 5. bypass-text-only — plan identical to a silver text-only stream 1`] = `
|
|
1080
1084
|
{
|
|
1085
|
+
"authRequired": null,
|
|
1081
1086
|
"items": [
|
|
1082
1087
|
{
|
|
1083
1088
|
"directive": false,
|
|
@@ -1106,6 +1111,7 @@ exports[`corpus > 5. bypass-text-only — plan identical to a silver text-only s
|
|
|
1106
1111
|
|
|
1107
1112
|
exports[`corpus > 7. view-never-handshakes — channel-aware labels on both channels 1`] = `
|
|
1108
1113
|
{
|
|
1114
|
+
"authRequired": null,
|
|
1109
1115
|
"items": [
|
|
1110
1116
|
{
|
|
1111
1117
|
"directive": false,
|
|
@@ -1214,6 +1220,7 @@ exports[`corpus > 7. view-never-handshakes — channel-aware labels on both chan
|
|
|
1214
1220
|
|
|
1215
1221
|
exports[`corpus > 8. aborted-mid-stream — partial kept + Stopped.; no orphaned spinner 1`] = `
|
|
1216
1222
|
{
|
|
1223
|
+
"authRequired": null,
|
|
1217
1224
|
"items": [
|
|
1218
1225
|
{
|
|
1219
1226
|
"directive": false,
|
|
@@ -1260,6 +1267,7 @@ exports[`corpus > 8. aborted-mid-stream — partial kept + Stopped.; no orphaned
|
|
|
1260
1267
|
|
|
1261
1268
|
exports[`corpus > 9. history-dead-locators — the expired path beside a healthy card 1`] = `
|
|
1262
1269
|
{
|
|
1270
|
+
"authRequired": null,
|
|
1263
1271
|
"items": [
|
|
1264
1272
|
{
|
|
1265
1273
|
"directive": false,
|
|
@@ -1339,6 +1347,7 @@ exports[`corpus > 9. history-dead-locators — the expired path beside a healthy
|
|
|
1339
1347
|
|
|
1340
1348
|
exports[`corpus > 10. empty-turn — status resolves, no empty bubble 1`] = `
|
|
1341
1349
|
{
|
|
1350
|
+
"authRequired": null,
|
|
1342
1351
|
"items": [
|
|
1343
1352
|
{
|
|
1344
1353
|
"directive": false,
|
|
@@ -1358,6 +1367,7 @@ exports[`corpus > 10. empty-turn — status resolves, no empty bubble 1`] = `
|
|
|
1358
1367
|
|
|
1359
1368
|
exports[`corpus > 11. unknown-block-storm — labeled rows; nothing blank, nothing raw in calm 1`] = `
|
|
1360
1369
|
{
|
|
1370
|
+
"authRequired": null,
|
|
1361
1371
|
"items": [
|
|
1362
1372
|
{
|
|
1363
1373
|
"directive": false,
|
|
@@ -1404,6 +1414,7 @@ exports[`corpus > 11. unknown-block-storm — labeled rows; nothing blank, nothi
|
|
|
1404
1414
|
|
|
1405
1415
|
exports[`corpus > 12. interleaved-media-code-citations — ordering and aggregation 1`] = `
|
|
1406
1416
|
{
|
|
1417
|
+
"authRequired": null,
|
|
1407
1418
|
"items": [
|
|
1408
1419
|
{
|
|
1409
1420
|
"directive": false,
|
|
@@ -1470,6 +1481,7 @@ exports[`corpus > 12. interleaved-media-code-citations — ordering and aggregat
|
|
|
1470
1481
|
|
|
1471
1482
|
exports[`corpus > 13. saturated-then-served — only R12 waiting, then a normal turn 1`] = `
|
|
1472
1483
|
{
|
|
1484
|
+
"authRequired": null,
|
|
1473
1485
|
"items": [
|
|
1474
1486
|
{
|
|
1475
1487
|
"directive": false,
|
|
@@ -1498,6 +1510,7 @@ exports[`corpus > 13. saturated-then-served — only R12 waiting, then a normal
|
|
|
1498
1510
|
|
|
1499
1511
|
exports[`corpus > 14. reasoning-heavy — calm collapses to one line; debug expands 1`] = `
|
|
1500
1512
|
{
|
|
1513
|
+
"authRequired": null,
|
|
1501
1514
|
"items": [
|
|
1502
1515
|
{
|
|
1503
1516
|
"directive": false,
|
|
@@ -1534,6 +1547,7 @@ exports[`corpus > 14. reasoning-heavy — calm collapses to one line; debug expa
|
|
|
1534
1547
|
|
|
1535
1548
|
exports[`corpus > 15. tools-around-a-view — the group SPLITS at the view's position 1`] = `
|
|
1536
1549
|
{
|
|
1550
|
+
"authRequired": null,
|
|
1537
1551
|
"items": [
|
|
1538
1552
|
{
|
|
1539
1553
|
"directive": false,
|
|
@@ -1702,6 +1716,7 @@ exports[`corpus > 15. tools-around-a-view — the group SPLITS at the view's pos
|
|
|
1702
1716
|
|
|
1703
1717
|
exports[`corpus > 16. user-send-failure — R0 failed with retry; the message never disappears 1`] = `
|
|
1704
1718
|
{
|
|
1719
|
+
"authRequired": null,
|
|
1705
1720
|
"items": [
|
|
1706
1721
|
{
|
|
1707
1722
|
"directive": false,
|
|
@@ -1721,6 +1736,7 @@ exports[`corpus > 16. user-send-failure — R0 failed with retry; the message ne
|
|
|
1721
1736
|
|
|
1722
1737
|
exports[`corpus > 19. persisted-plus-live — the fold owns its trailing turns; the prefix stays flat; overlapping cards dedupe 1`] = `
|
|
1723
1738
|
{
|
|
1739
|
+
"authRequired": null,
|
|
1724
1740
|
"items": [
|
|
1725
1741
|
{
|
|
1726
1742
|
"directive": false,
|
|
@@ -1871,6 +1887,7 @@ exports[`corpus > 19. persisted-plus-live — the fold owns its trailing turns;
|
|
|
1871
1887
|
|
|
1872
1888
|
exports[`corpus > 20. hitl-grant-modes — the persisted declaration renders; answers echo; cancelled re-asks (draft.2) 1`] = `
|
|
1873
1889
|
{
|
|
1890
|
+
"authRequired": null,
|
|
1874
1891
|
"items": [
|
|
1875
1892
|
{
|
|
1876
1893
|
"directive": false,
|
|
@@ -1941,6 +1958,7 @@ exports[`corpus > 20. hitl-grant-modes — the persisted declaration renders; an
|
|
|
1941
1958
|
|
|
1942
1959
|
exports[`corpus > 21. notice-rows — both arrival paths render labeled, never agent-voiced (draft.2) 1`] = `
|
|
1943
1960
|
{
|
|
1961
|
+
"authRequired": null,
|
|
1944
1962
|
"items": [
|
|
1945
1963
|
{
|
|
1946
1964
|
"expanded": true,
|
|
@@ -1985,6 +2003,7 @@ exports[`corpus > 21. notice-rows — both arrival paths render labeled, never a
|
|
|
1985
2003
|
|
|
1986
2004
|
exports[`corpus > 22. promoted-view — the stage's mount chips (guuey#204); others stay; no/stale key = no-op 1`] = `
|
|
1987
2005
|
{
|
|
2006
|
+
"authRequired": null,
|
|
1988
2007
|
"items": [
|
|
1989
2008
|
{
|
|
1990
2009
|
"directive": false,
|
|
@@ -2090,6 +2109,7 @@ exports[`corpus > 22. promoted-view — the stage's mount chips (guuey#204); oth
|
|
|
2090
2109
|
|
|
2091
2110
|
exports[`corpus > 23. meta-less-locator — a \`_meta\`-withholding producer's render still mounts (as a locator), never dark (guuey#209) 1`] = `
|
|
2092
2111
|
{
|
|
2112
|
+
"authRequired": null,
|
|
2093
2113
|
"items": [
|
|
2094
2114
|
{
|
|
2095
2115
|
"directive": false,
|
|
@@ -2150,6 +2170,7 @@ exports[`corpus > 23. meta-less-locator — a \`_meta\`-withholding producer's r
|
|
|
2150
2170
|
|
|
2151
2171
|
exports[`corpus > 24. prod-wire-ggui-render — ggui's production posture: no _meta, no uiData, a structuredContent locator → mounts as a locator (guuey#209) 1`] = `
|
|
2152
2172
|
{
|
|
2173
|
+
"authRequired": null,
|
|
2153
2174
|
"items": [
|
|
2154
2175
|
{
|
|
2155
2176
|
"directive": false,
|
|
@@ -2219,6 +2240,7 @@ exports[`corpus > 24. prod-wire-ggui-render — ggui's production posture: no _m
|
|
|
2219
2240
|
|
|
2220
2241
|
exports[`corpus > 25. chips-presentation — EVERY view chips; the promoted key marks the selection; views roster carries the mounts (guuey#301) 1`] = `
|
|
2221
2242
|
{
|
|
2243
|
+
"authRequired": null,
|
|
2222
2244
|
"items": [
|
|
2223
2245
|
{
|
|
2224
2246
|
"directive": false,
|
|
@@ -2313,6 +2335,7 @@ exports[`corpus > 25. chips-presentation — EVERY view chips; the promoted key
|
|
|
2313
2335
|
|
|
2314
2336
|
exports[`corpus > 25. oauth-auth-ask — kind:auth + authConfig oauth2 plans as the SAME hitl card with an oauth arm; a mode pick is a link, not an answer (guuey#178) 1`] = `
|
|
2315
2337
|
{
|
|
2338
|
+
"authRequired": null,
|
|
2316
2339
|
"items": [
|
|
2317
2340
|
{
|
|
2318
2341
|
"directive": false,
|
|
@@ -2382,6 +2405,7 @@ exports[`corpus > 25. oauth-auth-ask — kind:auth + authConfig oauth2 plans as
|
|
|
2382
2405
|
"oauth": {
|
|
2383
2406
|
"authorizationUrl": "https://mcp.dev.sandbox.guuey.com/oauth/start?state=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
2384
2407
|
"scopes": [],
|
|
2408
|
+
"upfront": false,
|
|
2385
2409
|
},
|
|
2386
2410
|
"promptId": "mcp-oauth:app_1:linear:thread-oauth",
|
|
2387
2411
|
"promptKind": "hitl",
|
package/src/index.ts
CHANGED
|
@@ -37,10 +37,14 @@ export {
|
|
|
37
37
|
OAUTH_LINK_PARAMS,
|
|
38
38
|
OAUTH_RETURN_PARAMS,
|
|
39
39
|
OAUTH_SCHEME,
|
|
40
|
+
OAUTH_UPFRONT_METADATA,
|
|
41
|
+
authRequiredFromAsks,
|
|
40
42
|
oauthAuthorizeAsk,
|
|
41
43
|
oauthAuthorizeHref,
|
|
42
44
|
parseOAuthReturn,
|
|
43
45
|
stripOAuthReturn,
|
|
46
|
+
type AuthRequired,
|
|
47
|
+
type AuthRequiredServer,
|
|
44
48
|
type OAuthAuthorizeAsk,
|
|
45
49
|
type OAuthReturn,
|
|
46
50
|
} from "./oauth.js";
|
package/src/oauth.ts
CHANGED
|
@@ -17,6 +17,15 @@
|
|
|
17
17
|
* `?error=<reason>` on failure). The broker allowlists it; the client
|
|
18
18
|
* just says where it lives.
|
|
19
19
|
*
|
|
20
|
+
* ## Required before use (guuey#605)
|
|
21
|
+
*
|
|
22
|
+
* An ask whose `metadata.authMode` is `"upfront"` is not an aside: the
|
|
23
|
+
* runtime REFUSED the turn on it (no model call, no agent answer) and will
|
|
24
|
+
* refuse every turn until the account is connected. {@link authRequiredFromAsks}
|
|
25
|
+
* lifts that off a turn's pending asks as {@link AuthRequired}, naming the
|
|
26
|
+
* servers, so a surface renders the connect step FIRST and stops inviting
|
|
27
|
+
* messages that cannot be answered.
|
|
28
|
+
*
|
|
20
29
|
* On return the surface strips the two params, shows a one-line notice, and
|
|
21
30
|
* does nothing else: the NEXT turn's pre-turn preflight on the pod resolves
|
|
22
31
|
* `connected` (or asks again). No client-side state survives the redirect
|
|
@@ -37,10 +46,41 @@ export const OAUTH_LINK_PARAMS = { mode: "mode", returnTo: "returnTo" } as const
|
|
|
37
46
|
/** The query params the broker's callback appends to `returnTo`. */
|
|
38
47
|
export const OAUTH_RETURN_PARAMS = { connected: "connected", error: "error" } as const;
|
|
39
48
|
|
|
49
|
+
/**
|
|
50
|
+
* The producer's ask-metadata contract for guuey#605 (`authMode:'upfront'` —
|
|
51
|
+
* require sign-in BEFORE use). SYNC with the runtime's
|
|
52
|
+
* `mcp-oauth-consent.ts#MCP_OAUTH_METADATA_AUTH_MODE`; the corpus fixture
|
|
53
|
+
* pins the pair. An ON-DEMAND ask carries none of these keys, so a lazy
|
|
54
|
+
* stream stays byte-identical to its pre-#605 shape.
|
|
55
|
+
*/
|
|
56
|
+
export const OAUTH_UPFRONT_METADATA = {
|
|
57
|
+
/** Carries `"upfront"`, and only that. */
|
|
58
|
+
authMode: "authMode",
|
|
59
|
+
/** The value the key ever carries. */
|
|
60
|
+
upfront: "upfront",
|
|
61
|
+
/** The server's human label, when the authorization server supplied one. */
|
|
62
|
+
displayName: "displayName",
|
|
63
|
+
/** The declared `mcpServers` key — the server's identity in every surface. */
|
|
64
|
+
serverName: "serverName",
|
|
65
|
+
} as const;
|
|
66
|
+
|
|
40
67
|
/** What an auth ask declares once narrowed to the OAuth arm. */
|
|
41
68
|
export interface OAuthAuthorizeAsk {
|
|
42
69
|
authorizationUrl: string;
|
|
43
70
|
scopes: readonly string[];
|
|
71
|
+
/**
|
|
72
|
+
* guuey#605 — this connection is REQUIRED BEFORE USE: the runtime refused
|
|
73
|
+
* the turn (no model call, no agent answer) and will keep refusing until
|
|
74
|
+
* the account is connected. Surfaces frame the card as the connect step
|
|
75
|
+
* rather than an aside. `false` = today's on-demand ask.
|
|
76
|
+
*/
|
|
77
|
+
upfront: boolean;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Read one string off an ask's metadata; `null` for absent or non-string. */
|
|
81
|
+
function metadataString(ask: AgPausedAsk, key: string): string | null {
|
|
82
|
+
const value = ask.metadata?.[key];
|
|
83
|
+
return typeof value === "string" && value !== "" ? value : null;
|
|
44
84
|
}
|
|
45
85
|
|
|
46
86
|
/**
|
|
@@ -53,7 +93,60 @@ export function oauthAuthorizeAsk(ask: AgPausedAsk): OAuthAuthorizeAsk | null {
|
|
|
53
93
|
if (ask.kind !== "auth" || ask.authConfig === undefined) return null;
|
|
54
94
|
const { scheme, authorizationUrl, scopes } = ask.authConfig;
|
|
55
95
|
if (scheme !== OAUTH_SCHEME || authorizationUrl === undefined || authorizationUrl === "") return null;
|
|
56
|
-
return {
|
|
96
|
+
return {
|
|
97
|
+
authorizationUrl,
|
|
98
|
+
scopes: scopes ?? [],
|
|
99
|
+
upfront: metadataString(ask, OAUTH_UPFRONT_METADATA.authMode) === OAUTH_UPFRONT_METADATA.upfront,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** One server the user must connect before the agent will answer. */
|
|
104
|
+
export interface AuthRequiredServer {
|
|
105
|
+
/** The declared `mcpServers` key; the askId's own suffix when the ask carries no metadata. */
|
|
106
|
+
serverName: string;
|
|
107
|
+
/** What to call it in copy — the authorization server's label, else `serverName`. */
|
|
108
|
+
label: string;
|
|
109
|
+
/** The ask to render as the connect step (its `authorizationUrl` is the door). */
|
|
110
|
+
ask: AgPausedAsk;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* The typed refusal (guuey#605): the runtime would not run this agent
|
|
115
|
+
* because one or more `authMode:'upfront'` OAuth servers have no live
|
|
116
|
+
* connection for this end user. Derived from the PENDING asks of the
|
|
117
|
+
* transcript — a settled or dismissed ask never gates a surface (a "no"
|
|
118
|
+
* must not brick the chat; the pod simply re-cards on the next turn).
|
|
119
|
+
*/
|
|
120
|
+
export interface AuthRequired {
|
|
121
|
+
servers: readonly AuthRequiredServer[];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Read {@link AuthRequired} off a turn's asks. `null` when nothing upfront
|
|
126
|
+
* is pending — the ONLY signal a surface should gate its composer on.
|
|
127
|
+
*
|
|
128
|
+
* Pass just the asks still awaiting an answer: a resolved / declined /
|
|
129
|
+
* dismissed record must not hold the door shut, because the client is not
|
|
130
|
+
* the enforcer here. The POD is: it refuses each turn while the connection
|
|
131
|
+
* is missing and re-emits the card. This derivation exists so a surface can
|
|
132
|
+
* say so before the user spends a turn finding out.
|
|
133
|
+
*/
|
|
134
|
+
export function authRequiredFromAsks(asks: readonly AgPausedAsk[]): AuthRequired | null {
|
|
135
|
+
const servers: AuthRequiredServer[] = [];
|
|
136
|
+
const seen = new Set<string>();
|
|
137
|
+
for (const ask of asks) {
|
|
138
|
+
const oauth = oauthAuthorizeAsk(ask);
|
|
139
|
+
if (oauth === null || !oauth.upfront) continue;
|
|
140
|
+
const serverName = metadataString(ask, OAUTH_UPFRONT_METADATA.serverName) ?? ask.askId;
|
|
141
|
+
if (seen.has(serverName)) continue;
|
|
142
|
+
seen.add(serverName);
|
|
143
|
+
servers.push({
|
|
144
|
+
serverName,
|
|
145
|
+
label: metadataString(ask, OAUTH_UPFRONT_METADATA.displayName) ?? serverName,
|
|
146
|
+
ask,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
return servers.length === 0 ? null : { servers };
|
|
57
150
|
}
|
|
58
151
|
|
|
59
152
|
/**
|
package/src/plan.ts
CHANGED
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
} from "@guuey/mcp-apps-host";
|
|
42
42
|
import type { TranscriptPolicy } from "./policy.js";
|
|
43
43
|
import { grantModeDisplay } from "./hitl.js";
|
|
44
|
-
import { oauthAuthorizeAsk } from "./oauth.js";
|
|
44
|
+
import { authRequiredFromAsks, oauthAuthorizeAsk } from "./oauth.js";
|
|
45
45
|
import type {
|
|
46
46
|
CitationsItem,
|
|
47
47
|
DataResultItem,
|
|
@@ -1111,6 +1111,13 @@ export function planTranscript(
|
|
|
1111
1111
|
recovery:
|
|
1112
1112
|
inputs.adopted === true && policy.debugDetail ? policy.strings.recoveredFromHistory : null,
|
|
1113
1113
|
views,
|
|
1114
|
+
// guuey#605 — the typed refusal, derived from the PENDING hitl asks only.
|
|
1115
|
+
// A settled or dismissed record never gates the surface: the pod is the
|
|
1116
|
+
// enforcer (it refuses each turn and re-cards), and a "no" that locked the
|
|
1117
|
+
// composer would dead-end a user who cannot un-dismiss.
|
|
1118
|
+
authRequired: authRequiredFromAsks(
|
|
1119
|
+
inputs.prompts.flatMap((p) => (p.kind === "hitl" && p.state === "pending" ? [p.ask] : [])),
|
|
1120
|
+
),
|
|
1114
1121
|
};
|
|
1115
1122
|
}
|
|
1116
1123
|
|
package/src/react/components.tsx
CHANGED
|
@@ -569,8 +569,15 @@ export function DefaultPrompt({ item, ctx }: ItemProps<PromptItem>): ReactNode {
|
|
|
569
569
|
);
|
|
570
570
|
}
|
|
571
571
|
const answerable = item.state === "pending" || (item.state === "cancelled" && item.expanded);
|
|
572
|
+
// guuey#605 — a REQUIRED connection is a step, not an aside: the runtime
|
|
573
|
+
// refused this turn on it and answers nothing until it is connected. The
|
|
574
|
+
// card says so above the ask, and carries a class a theme can lift.
|
|
575
|
+
const requiredConnection = item.oauth?.upfront === true;
|
|
572
576
|
return (
|
|
573
|
-
<div
|
|
577
|
+
<div
|
|
578
|
+
className={`guuey-chat-prompt${requiredConnection ? " guuey-chat-prompt-required" : ""}`}
|
|
579
|
+
role="group"
|
|
580
|
+
>
|
|
574
581
|
{item.state === "cancelled" && (
|
|
575
582
|
<button
|
|
576
583
|
type="button"
|
|
@@ -583,6 +590,9 @@ export function DefaultPrompt({ item, ctx }: ItemProps<PromptItem>): ReactNode {
|
|
|
583
590
|
)}
|
|
584
591
|
{answerable && (
|
|
585
592
|
<>
|
|
593
|
+
{requiredConnection && (
|
|
594
|
+
<p className="guuey-chat-prompt-required-hint">{s.authRequiredHint}</p>
|
|
595
|
+
)}
|
|
586
596
|
{item.message !== null && <p className="guuey-chat-prompt-ask">{item.message}</p>}
|
|
587
597
|
<div className="guuey-chat-prompt-actions">
|
|
588
598
|
{item.grantModes.length === 0 ? (
|
package/src/react/guuey-chat.tsx
CHANGED
|
@@ -24,6 +24,12 @@
|
|
|
24
24
|
* (partial text kept, "Stopped." marked — the hook's contract).
|
|
25
25
|
* - Enter sends; Shift+Enter inserts a newline; an IME-composing Enter
|
|
26
26
|
* never sends (the candidate commit is not a submit).
|
|
27
|
+
* - `plan.authRequired !== null` (guuey#605 — an `authMode:'upfront'` OAuth
|
|
28
|
+
* server is pending connection) → input disabled, `composerAuthRequired`
|
|
29
|
+
* placeholder, Send gated, and a connect-first line above the composer.
|
|
30
|
+
* The RUNTIME is the enforcer (it refuses every turn before any model
|
|
31
|
+
* call); this only stops the user spending a message to learn that.
|
|
32
|
+
* Dismissing the card releases the gate — no dead end.
|
|
27
33
|
*
|
|
28
34
|
* ## History
|
|
29
35
|
*
|
|
@@ -574,8 +580,15 @@ export const GuueyChat = forwardRef<GuueyChatHandle, GuueyChatProps>(function Gu
|
|
|
574
580
|
// when several chats mount on one page — a static id would collide.
|
|
575
581
|
const composerId = useId();
|
|
576
582
|
const busy = invoke.status !== "ready";
|
|
583
|
+
// guuey#605 — the connect-first gate. While an `authMode:'upfront'` OAuth
|
|
584
|
+
// server is pending connection the RUNTIME refuses every turn before any
|
|
585
|
+
// model call, so inviting a message here would only spend one to be told
|
|
586
|
+
// the same thing. The gate is the plan's typed refusal, and it releases the
|
|
587
|
+
// moment the card is dismissed or answered (the pod re-cards next turn) —
|
|
588
|
+
// the client never claims more than the pod enforces, and no one dead-ends.
|
|
589
|
+
const authRequired = plan.authRequired;
|
|
577
590
|
const available = endpointUrl !== null;
|
|
578
|
-
const canSend = available && !busy && input.trim() !== "";
|
|
591
|
+
const canSend = available && !busy && authRequired === null && input.trim() !== "";
|
|
579
592
|
|
|
580
593
|
// ── The imperative seam (guuey#210) ──────────────────────────────────
|
|
581
594
|
// ONE stable handle for the component's whole life (hosts capture it in
|
|
@@ -888,12 +901,14 @@ export const GuueyChat = forwardRef<GuueyChatHandle, GuueyChatProps>(function Gu
|
|
|
888
901
|
|
|
889
902
|
const submit = useCallback((): void => {
|
|
890
903
|
const text = input.trim();
|
|
891
|
-
|
|
904
|
+
// guuey#605: the connect-first gate belongs on the SEND path too, not
|
|
905
|
+
// just the disabled attribute — an Enter keypress reaches here directly.
|
|
906
|
+
if (text === "" || !available || busy || authRequired !== null) return;
|
|
892
907
|
setInput("");
|
|
893
908
|
void invoke.send(text).catch(() => {
|
|
894
909
|
// The hook surfaces the failure (`error` / R0 failed-send).
|
|
895
910
|
});
|
|
896
|
-
}, [input, available, busy, invoke]);
|
|
911
|
+
}, [input, available, busy, authRequired, invoke]);
|
|
897
912
|
|
|
898
913
|
const handleRetry = useCallback(
|
|
899
914
|
(item: UserMessageItem) => {
|
|
@@ -1035,6 +1050,16 @@ export const GuueyChat = forwardRef<GuueyChatHandle, GuueyChatProps>(function Gu
|
|
|
1035
1050
|
</button>
|
|
1036
1051
|
</p>
|
|
1037
1052
|
)}
|
|
1053
|
+
{authRequired !== null && (
|
|
1054
|
+
<p role="status" className="guuey-chat-auth-required">
|
|
1055
|
+
<strong className="guuey-chat-auth-required-heading">
|
|
1056
|
+
{strings.authRequiredHeading(
|
|
1057
|
+
authRequired.servers.map((s) => s.label).join(", "),
|
|
1058
|
+
)}
|
|
1059
|
+
</strong>
|
|
1060
|
+
<span className="guuey-chat-auth-required-hint">{strings.authRequiredHint}</span>
|
|
1061
|
+
</p>
|
|
1062
|
+
)}
|
|
1038
1063
|
{composer && (
|
|
1039
1064
|
<form
|
|
1040
1065
|
className="guuey-chat-composer"
|
|
@@ -1059,9 +1084,15 @@ export const GuueyChat = forwardRef<GuueyChatHandle, GuueyChatProps>(function Gu
|
|
|
1059
1084
|
submit();
|
|
1060
1085
|
}
|
|
1061
1086
|
}}
|
|
1062
|
-
disabled={!available}
|
|
1087
|
+
disabled={!available || authRequired !== null}
|
|
1063
1088
|
aria-label={strings.composerLabel}
|
|
1064
|
-
placeholder={
|
|
1089
|
+
placeholder={
|
|
1090
|
+
!available
|
|
1091
|
+
? strings.composerUnavailable
|
|
1092
|
+
: authRequired !== null
|
|
1093
|
+
? strings.composerAuthRequired
|
|
1094
|
+
: strings.composerPlaceholder
|
|
1095
|
+
}
|
|
1065
1096
|
/>
|
|
1066
1097
|
{busy ? (
|
|
1067
1098
|
<button
|
package/src/strings.ts
CHANGED
|
@@ -125,6 +125,17 @@ export interface ChatStrings {
|
|
|
125
125
|
oauthConnected: (serverName: string) => string;
|
|
126
126
|
oauthFailed: (reason: string) => string;
|
|
127
127
|
|
|
128
|
+
/**
|
|
129
|
+
* The `authMode:'upfront'` connect-first framing (guuey#605): the agent
|
|
130
|
+
* cannot answer at all until these accounts are connected, so the card
|
|
131
|
+
* reads as a step and the composer says why it is holding.
|
|
132
|
+
* `authRequiredHeading` takes the servers' labels already joined for
|
|
133
|
+
* display; `composerAuthRequired` is the held composer's placeholder.
|
|
134
|
+
*/
|
|
135
|
+
authRequiredHeading: (serverLabels: string) => string;
|
|
136
|
+
authRequiredHint: string;
|
|
137
|
+
composerAuthRequired: string;
|
|
138
|
+
|
|
128
139
|
/** R16 — the notice row's label (provenance shows only under debug). */
|
|
129
140
|
noticeLabel: string;
|
|
130
141
|
|
|
@@ -253,6 +264,10 @@ export const defaultChatStrings: ChatStrings = {
|
|
|
253
264
|
oauthConnected: (serverName) => `Connected ${serverName}. The agent can use it from your next message.`,
|
|
254
265
|
oauthFailed: (reason) => `Couldn't connect: ${reason}`,
|
|
255
266
|
|
|
267
|
+
authRequiredHeading: (serverLabels) => `Connect ${serverLabels} to start`,
|
|
268
|
+
authRequiredHint: "This agent needs the account before it can answer.",
|
|
269
|
+
composerAuthRequired: "Connect the account above to start.",
|
|
270
|
+
|
|
256
271
|
noticeLabel: "Note",
|
|
257
272
|
|
|
258
273
|
linkAskLabel: (host) => `This card wants to open ${host}`,
|
package/src/types.ts
CHANGED
|
@@ -26,6 +26,7 @@ import type {
|
|
|
26
26
|
ViewMount,
|
|
27
27
|
ViewMountChannel,
|
|
28
28
|
} from "@guuey/mcp-apps-host";
|
|
29
|
+
import type { AuthRequired, OAuthAuthorizeAsk } from "./oauth.js";
|
|
29
30
|
|
|
30
31
|
/**
|
|
31
32
|
* One settled entry of the flat conversation transcript — structurally
|
|
@@ -395,9 +396,11 @@ export interface HitlPromptItem extends BaseItem {
|
|
|
395
396
|
* `authConfig.scheme:"oauth2"` + an `authorizationUrl`. There is no
|
|
396
397
|
* answer door for this ask — a mode pick OPENS `authorizationUrl` with
|
|
397
398
|
* `&mode=` + `&returnTo=` appended (`oauthAuthorizeHref`); "Not now" is a
|
|
398
|
-
* plain dismissal. `null` for every other ask.
|
|
399
|
+
* plain dismissal. `null` for every other ask. `upfront` (guuey#605) marks
|
|
400
|
+
* a connection REQUIRED BEFORE USE — the turn carrying this ask was
|
|
401
|
+
* refused, not answered.
|
|
399
402
|
*/
|
|
400
|
-
oauth:
|
|
403
|
+
oauth: OAuthAuthorizeAsk | null;
|
|
401
404
|
state: "pending" | "resolved" | "declined" | "cancelled";
|
|
402
405
|
/** Echo of the chosen mode id (identity, never displayed as meaning). */
|
|
403
406
|
chosenModeId: string | null;
|
|
@@ -598,4 +601,13 @@ export interface TranscriptPlan {
|
|
|
598
601
|
* mount even when the transcript shows only chips.
|
|
599
602
|
*/
|
|
600
603
|
views: PlanViewSummary[];
|
|
604
|
+
/**
|
|
605
|
+
* guuey#605 — the typed refusal: non-null while one or more
|
|
606
|
+
* `authMode:'upfront'` OAuth servers are PENDING connection, naming them.
|
|
607
|
+
* The runtime refuses every turn (no model call) until they are connected,
|
|
608
|
+
* so a surface renders the connect step first and holds its composer; a
|
|
609
|
+
* dismissed card releases the gate (the pod re-cards next turn — a "no"
|
|
610
|
+
* never bricks the chat). `null` on every ordinary plan.
|
|
611
|
+
*/
|
|
612
|
+
authRequired: AuthRequired | null;
|
|
601
613
|
}
|