Fix WS auth + gym release directive TypeScript error (#16)
* Fix WS auth: wire accessGate.allowUpgrade via verifyClient The allowWs callback was never actually calling accessGate.allowUpgrade during the WS handshake - the ws library passes (info) not (req), and verifyClient must be set on the WebSocketServer constructor options. Fix: pass verifyClient to WebSocketServer constructor and wrap allowUpgrade to extract info.req. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix TypeScript error and add gym release directive support Add "release" value to OfficeGymDirective type for symmetry with OfficeQaDirective ("qa_lab" | "release"). Previously OfficeGymDirective was only "gym" with no release state, making the "!== 'release'" check in eventTriggers.ts dead code that TypeScript flagged as an unintentional comparison. Changes: - deskDirectives.ts: add "release" to OfficeGymDirective type - deskDirectives.ts: add gym release patterns to skill and command directive resolvers (e.g. "leave the gym", "done with skills") - eventTriggers.ts: change !== "release" to === "gym" for clarity and consistency with reduceOfficeGymHoldState pattern This fixes: https://github.com/iamlukethedev/Claw3D/issues/15 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -87,11 +87,13 @@ function createGatewayProxy(options) {
|
|||||||
logError = (msg, err) => console.error(msg, err),
|
logError = (msg, err) => console.error(msg, err),
|
||||||
} = options || {};
|
} = options || {};
|
||||||
|
|
||||||
|
const { verifyClient } = options || {};
|
||||||
|
|
||||||
if (typeof loadUpstreamSettings !== "function") {
|
if (typeof loadUpstreamSettings !== "function") {
|
||||||
throw new Error("createGatewayProxy requires loadUpstreamSettings().");
|
throw new Error("createGatewayProxy requires loadUpstreamSettings().");
|
||||||
}
|
}
|
||||||
|
|
||||||
const wss = new WebSocketServer({ noServer: true });
|
const wss = new WebSocketServer({ noServer: true, verifyClient });
|
||||||
|
|
||||||
wss.on("connection", (browserWs) => {
|
wss.on("connection", (browserWs) => {
|
||||||
let upstreamWs = null;
|
let upstreamWs = null;
|
||||||
|
|||||||
+1
-1
@@ -50,9 +50,9 @@ async function main() {
|
|||||||
},
|
},
|
||||||
allowWs: (req) => {
|
allowWs: (req) => {
|
||||||
if (resolvePathname(req.url) !== "/api/gateway/ws") return false;
|
if (resolvePathname(req.url) !== "/api/gateway/ws") return false;
|
||||||
if (!accessGate.allowUpgrade(req)) return false;
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
verifyClient: (info) => accessGate.allowUpgrade(info.req),
|
||||||
});
|
});
|
||||||
|
|
||||||
await app.prepare();
|
await app.prepare();
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { stripUiMetadata } from "@/lib/text/message-extract";
|
|||||||
// regex checks across chat, office, or scene code.
|
// regex checks across chat, office, or scene code.
|
||||||
export type OfficeDeskDirective = "desk" | "release";
|
export type OfficeDeskDirective = "desk" | "release";
|
||||||
export type OfficeGithubDirective = "github" | "release";
|
export type OfficeGithubDirective = "github" | "release";
|
||||||
export type OfficeGymDirective = "gym";
|
export type OfficeGymDirective = "gym" | "release";
|
||||||
export type OfficeQaDirective = "qa_lab" | "release";
|
export type OfficeQaDirective = "qa_lab" | "release";
|
||||||
export type OfficeStandupDirective = "standup";
|
export type OfficeStandupDirective = "standup";
|
||||||
export type OfficeCallPhase = "needs_message" | "ready_to_call";
|
export type OfficeCallPhase = "needs_message" | "ready_to_call";
|
||||||
@@ -156,6 +156,16 @@ const resolveOfficeInteractionDirectiveFromNormalized = (
|
|||||||
const resolveOfficeGymSkillDirectiveFromNormalized = (
|
const resolveOfficeGymSkillDirectiveFromNormalized = (
|
||||||
normalized: string,
|
normalized: string,
|
||||||
): OfficeGymDirective | null => {
|
): OfficeGymDirective | null => {
|
||||||
|
const gymSkillReleasePatterns = [
|
||||||
|
/\bleave\s+(?:the\s+)?gym\b/,
|
||||||
|
/\bexit\s+(?:the\s+)?gym\b/,
|
||||||
|
/\bdone\s+(?:with\s+(?:the\s+)?)?(?:gym|skill(?:\s+building)?)\b/,
|
||||||
|
/\bstop\s+(?:working\s+on\s+)?skills?\b/,
|
||||||
|
/\bleave\s+the\s+skill(?:\s+building)?(?:\s+room)?\b/,
|
||||||
|
];
|
||||||
|
if (gymSkillReleasePatterns.some((pattern) => pattern.test(normalized))) {
|
||||||
|
return "release";
|
||||||
|
}
|
||||||
const skillIntentPatterns = [
|
const skillIntentPatterns = [
|
||||||
/\bskills?\b/,
|
/\bskills?\b/,
|
||||||
/\bskills?\s+marketplace\b/,
|
/\bskills?\s+marketplace\b/,
|
||||||
@@ -177,6 +187,16 @@ const resolveOfficeGymSkillDirectiveFromNormalized = (
|
|||||||
const resolveOfficeGymCommandDirectiveFromNormalized = (
|
const resolveOfficeGymCommandDirectiveFromNormalized = (
|
||||||
normalized: string,
|
normalized: string,
|
||||||
): OfficeGymDirective | null => {
|
): OfficeGymDirective | null => {
|
||||||
|
const gymCommandReleasePatterns = [
|
||||||
|
/\bleave\s+(?:the\s+)?gym\b/,
|
||||||
|
/\bexit\s+(?:the\s+)?gym\b/,
|
||||||
|
/\bdone\s+(?:with\s+(?:the\s+)?)?gym\b/,
|
||||||
|
/\bstop\s+gym(?:ning)?\b/,
|
||||||
|
/\bleave\s+skill(?:\s+building)?(?:\s+room)?\b/,
|
||||||
|
];
|
||||||
|
if (gymCommandReleasePatterns.some((pattern) => pattern.test(normalized))) {
|
||||||
|
return "release";
|
||||||
|
}
|
||||||
const gymCommandPatterns = [
|
const gymCommandPatterns = [
|
||||||
/\b(?:lets|let's)\s+go\s+to\s+the\s+gym\b/,
|
/\b(?:lets|let's)\s+go\s+to\s+the\s+gym\b/,
|
||||||
/\b(?:lets|let's)\s+go\s+to\s+gym\b/,
|
/\b(?:lets|let's)\s+go\s+to\s+gym\b/,
|
||||||
|
|||||||
@@ -1133,7 +1133,7 @@ export const reconcileOfficeAnimationTriggerState = (params: {
|
|||||||
});
|
});
|
||||||
if (skillGymDirective) {
|
if (skillGymDirective) {
|
||||||
skillGymDirectiveKeyByAgentId[agentId] = skillGymDirective.key;
|
skillGymDirectiveKeyByAgentId[agentId] = skillGymDirective.key;
|
||||||
if (skillGymDirective.directive !== "release") {
|
if (skillGymDirective.directive === "gym") {
|
||||||
skillGymHoldByAgentId[agentId] = true;
|
skillGymHoldByAgentId[agentId] = true;
|
||||||
}
|
}
|
||||||
} else if (next.skillGymHoldByAgentId[agentId]) {
|
} else if (next.skillGymHoldByAgentId[agentId]) {
|
||||||
|
|||||||
Reference in New Issue
Block a user