@moxt-ai/mobius 0.0.21 → 0.0.23
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/bots/bot-context-applicator.d.ts +14 -0
- package/dist/bots/bot-context-applicator.d.ts.map +1 -0
- package/dist/bots/bot-context-applicator.js +32 -0
- package/dist/bots/bot-context-applicator.js.map +1 -0
- package/dist/bots/bot-execution-context.d.ts +20 -0
- package/dist/bots/bot-execution-context.d.ts.map +1 -0
- package/dist/bots/bot-execution-context.js +82 -0
- package/dist/bots/bot-execution-context.js.map +1 -0
- package/dist/bots/bot-message-command.d.ts +6 -0
- package/dist/bots/bot-message-command.d.ts.map +1 -0
- package/dist/bots/bot-message-command.js +140 -0
- package/dist/bots/bot-message-command.js.map +1 -0
- package/dist/bots/bot-outbound-ipc.d.ts +12 -0
- package/dist/bots/bot-outbound-ipc.d.ts.map +1 -0
- package/dist/bots/bot-outbound-ipc.js +245 -0
- package/dist/bots/bot-outbound-ipc.js.map +1 -0
- package/dist/bots/local-bot-grant-store.d.ts +34 -0
- package/dist/bots/local-bot-grant-store.d.ts.map +1 -0
- package/dist/bots/local-bot-grant-store.js +263 -0
- package/dist/bots/local-bot-grant-store.js.map +1 -0
- package/dist/cli.js +1872 -213
- package/dist/cli.js.map +4 -4
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1930 -280
- package/dist/index.js.map +4 -4
- package/dist/prompt-artifact-resolver.d.ts +8 -2
- package/dist/prompt-artifact-resolver.d.ts.map +1 -1
- package/dist/prompt-artifact-resolver.js.map +1 -1
- package/dist/run-daemon.d.ts.map +1 -1
- package/dist/run-daemon.js +241 -8
- package/dist/run-daemon.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BotSessionPromptCommand, PromptResource } from "@moxt-ai/mobius-protocol";
|
|
2
|
+
import type { LocalBotGrant } from "./local-bot-grant-store.ts";
|
|
3
|
+
export declare class AppliedBotContext {
|
|
4
|
+
readonly resources: readonly PromptResource[];
|
|
5
|
+
constructor(resources: readonly PromptResource[]);
|
|
6
|
+
}
|
|
7
|
+
interface BotContextApplicator {
|
|
8
|
+
readonly apply: (command: BotSessionPromptCommand, grant: LocalBotGrant, resources: readonly PromptResource[], signal: AbortSignal) => Promise<AppliedBotContext>;
|
|
9
|
+
}
|
|
10
|
+
export declare class EmbeddedBotContextApplicator implements BotContextApplicator {
|
|
11
|
+
readonly apply: (command: BotSessionPromptCommand, grant: LocalBotGrant, resources: readonly PromptResource[], signal: AbortSignal) => Promise<AppliedBotContext>;
|
|
12
|
+
}
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=bot-context-applicator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bot-context-applicator.d.ts","sourceRoot":"","sources":["../../src/bots/bot-context-applicator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAExF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAGhE,qBAAa,iBAAiB;IAC1B,QAAQ,CAAC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IAE9C,YAAY,SAAS,EAAE,SAAS,cAAc,EAAE,EAE/C;CACJ;AAED,UAAU,oBAAoB;IAC1B,QAAQ,CAAC,KAAK,EAAE,CACZ,OAAO,EAAE,uBAAuB,EAChC,KAAK,EAAE,aAAa,EACpB,SAAS,EAAE,SAAS,cAAc,EAAE,EACpC,MAAM,EAAE,WAAW,KAClB,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACnC;AAED,qBAAa,4BAA6B,YAAW,oBAAoB;IACrE,QAAQ,CAAC,KAAK,YACD,uBAAuB,SACzB,aAAa,aACT,SAAS,cAAc,EAAE,UAC5B,WAAW,KACpB,OAAO,CAAC,iBAAiB,CAAC,CA6B3B;CACL"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { LocalBotAuthorizationError } from "./local-bot-grant-store.js";
|
|
2
|
+
export class AppliedBotContext {
|
|
3
|
+
resources;
|
|
4
|
+
constructor(resources) {
|
|
5
|
+
this.resources = Object.freeze([...resources]);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export class EmbeddedBotContextApplicator {
|
|
9
|
+
apply = async (command, grant, resources, signal) => {
|
|
10
|
+
signal.throwIfAborted();
|
|
11
|
+
if (grant.botId !== command.botId ||
|
|
12
|
+
grant.behaviorRevisionId !== command.behaviorRevisionId ||
|
|
13
|
+
grant.behaviorDigest !== command.behaviorDigest) {
|
|
14
|
+
throw new LocalBotAuthorizationError("binding_not_approved", "The Bot behavior does not match its local authorization");
|
|
15
|
+
}
|
|
16
|
+
if (command.behaviorInstructions.length === 0) {
|
|
17
|
+
return new AppliedBotContext(resources);
|
|
18
|
+
}
|
|
19
|
+
if (!grant.agent.capabilities.embeddedContextPrompt) {
|
|
20
|
+
throw new LocalBotAuthorizationError("binding_incompatible", "The local Agent cannot enforce the Bot behavior context");
|
|
21
|
+
}
|
|
22
|
+
const trustedContext = {
|
|
23
|
+
mimeType: "text/markdown",
|
|
24
|
+
name: "Mobius Bot behavior",
|
|
25
|
+
text: command.behaviorInstructions,
|
|
26
|
+
type: "embedded",
|
|
27
|
+
uri: `mobius://bots/${encodeURIComponent(command.botId)}/behavior-revisions/${encodeURIComponent(command.behaviorRevisionId)}?sha256=${command.behaviorDigest}`,
|
|
28
|
+
};
|
|
29
|
+
return new AppliedBotContext([trustedContext, ...resources]);
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=bot-context-applicator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bot-context-applicator.js","sourceRoot":"","sources":["../../src/bots/bot-context-applicator.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAExE,MAAM,OAAO,iBAAiB;IACjB,SAAS,CAA4B;IAE9C,YAAY,SAAoC;QAC5C,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IACnD,CAAC;CACJ;AAWD,MAAM,OAAO,4BAA4B;IAC5B,KAAK,GAAG,KAAK,EAClB,OAAgC,EAChC,KAAoB,EACpB,SAAoC,EACpC,MAAmB,EACO,EAAE;QAC5B,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,IACI,KAAK,CAAC,KAAK,KAAK,OAAO,CAAC,KAAK;YAC7B,KAAK,CAAC,kBAAkB,KAAK,OAAO,CAAC,kBAAkB;YACvD,KAAK,CAAC,cAAc,KAAK,OAAO,CAAC,cAAc,EACjD,CAAC;YACC,MAAM,IAAI,0BAA0B,CAChC,sBAAsB,EACtB,yDAAyD,CAC5D,CAAC;QACN,CAAC;QACD,IAAI,OAAO,CAAC,oBAAoB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5C,OAAO,IAAI,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,qBAAqB,EAAE,CAAC;YAClD,MAAM,IAAI,0BAA0B,CAChC,sBAAsB,EACtB,yDAAyD,CAC5D,CAAC;QACN,CAAC;QACD,MAAM,cAAc,GAAmB;YACnC,QAAQ,EAAE,eAAe;YACzB,IAAI,EAAE,qBAAqB;YAC3B,IAAI,EAAE,OAAO,CAAC,oBAAoB;YAClC,IAAI,EAAE,UAAU;YAChB,GAAG,EAAE,iBAAiB,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,uBAAuB,kBAAkB,CAAC,OAAO,CAAC,kBAAkB,CAAC,WAAW,OAAO,CAAC,cAAc,EAAE;SAClK,CAAC;QACF,OAAO,IAAI,iBAAiB,CAAC,CAAC,cAAc,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC;CACL"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type BotSessionPromptCommand } from "@moxt-ai/mobius-protocol";
|
|
2
|
+
export declare class ActiveBotExecutionContext {
|
|
3
|
+
readonly command: BotSessionPromptCommand;
|
|
4
|
+
readonly contextHandle: string;
|
|
5
|
+
constructor(contextHandle: string, command: BotSessionPromptCommand);
|
|
6
|
+
readonly resolveTarget: (target: string) => string;
|
|
7
|
+
}
|
|
8
|
+
export declare class BotExecutionContextLease {
|
|
9
|
+
#private;
|
|
10
|
+
readonly context: ActiveBotExecutionContext;
|
|
11
|
+
constructor(context: ActiveBotExecutionContext, release: () => void);
|
|
12
|
+
readonly release: () => void;
|
|
13
|
+
}
|
|
14
|
+
export declare class BotExecutionContextRegistry {
|
|
15
|
+
#private;
|
|
16
|
+
constructor(now?: () => number);
|
|
17
|
+
readonly activate: (command: BotSessionPromptCommand) => BotExecutionContextLease;
|
|
18
|
+
readonly read: (handle: string) => ActiveBotExecutionContext;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=bot-execution-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bot-execution-context.d.ts","sourceRoot":"","sources":["../../src/bots/bot-execution-context.ts"],"names":[],"mappings":"AACA,OAAO,EAA2B,KAAK,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAIjG,qBAAa,yBAAyB;IAClC,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAC;IAC1C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAE/B,YAAY,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB,EAGlE;IAED,QAAQ,CAAC,aAAa,WAAY,MAAM,KAAG,MAAM,CAkB/C;CACL;AAED,qBAAa,wBAAwB;;IACjC,QAAQ,CAAC,OAAO,EAAE,yBAAyB,CAAC;IAI5C,YAAY,OAAO,EAAE,yBAAyB,EAAE,OAAO,EAAE,MAAM,IAAI,EAGlE;IAED,QAAQ,CAAC,OAAO,QAAO,IAAI,CAMzB;CACL;AAED,qBAAa,2BAA2B;;IAMpC,YAAY,GAAG,GAAE,MAAM,MAAiB,EAEvC;IAED,QAAQ,CAAC,QAAQ,YAAa,uBAAuB,KAAG,wBAAwB,CAkB9E;IAEF,QAAQ,CAAC,IAAI,WAAY,MAAM,KAAG,yBAAyB,CAqBzD;CACL"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { BotConnectionReplyRoute } from "@moxt-ai/mobius-protocol";
|
|
3
|
+
import { LocalBotAuthorizationError } from "./local-bot-grant-store.js";
|
|
4
|
+
export class ActiveBotExecutionContext {
|
|
5
|
+
command;
|
|
6
|
+
contextHandle;
|
|
7
|
+
constructor(contextHandle, command) {
|
|
8
|
+
this.contextHandle = contextHandle;
|
|
9
|
+
this.command = command;
|
|
10
|
+
}
|
|
11
|
+
resolveTarget = (target) => {
|
|
12
|
+
if (target === "current") {
|
|
13
|
+
if (!(this.command.replyRoute instanceof BotConnectionReplyRoute)) {
|
|
14
|
+
throw new LocalBotAuthorizationError("delivery_target_not_allowed", "This Bot conversation has no external reply target");
|
|
15
|
+
}
|
|
16
|
+
return this.command.replyRoute.deliveryTargetId;
|
|
17
|
+
}
|
|
18
|
+
const resolved = this.command.allowedDeliveryTargets.find((candidate) => candidate.alias === target);
|
|
19
|
+
if (resolved === undefined) {
|
|
20
|
+
throw new LocalBotAuthorizationError("delivery_target_not_allowed", "The named Bot delivery target is not approved");
|
|
21
|
+
}
|
|
22
|
+
return resolved.deliveryTargetId;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export class BotExecutionContextLease {
|
|
26
|
+
context;
|
|
27
|
+
#release;
|
|
28
|
+
#released = false;
|
|
29
|
+
constructor(context, release) {
|
|
30
|
+
this.context = context;
|
|
31
|
+
this.#release = release;
|
|
32
|
+
}
|
|
33
|
+
release = () => {
|
|
34
|
+
if (this.#released) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
this.#released = true;
|
|
38
|
+
this.#release();
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export class BotExecutionContextRegistry {
|
|
42
|
+
#activeByHandle = new Map();
|
|
43
|
+
#handlesBySession = new Map();
|
|
44
|
+
#inactiveHandles = new Set();
|
|
45
|
+
#now;
|
|
46
|
+
constructor(now = Date.now) {
|
|
47
|
+
this.#now = now;
|
|
48
|
+
}
|
|
49
|
+
activate = (command) => {
|
|
50
|
+
let handle = this.#handlesBySession.get(command.sessionId);
|
|
51
|
+
if (handle === undefined) {
|
|
52
|
+
handle = `ctx_${randomBytes(32).toString("base64url")}`;
|
|
53
|
+
this.#handlesBySession.set(command.sessionId, handle);
|
|
54
|
+
}
|
|
55
|
+
if (this.#activeByHandle.has(handle)) {
|
|
56
|
+
throw new LocalBotAuthorizationError("session_busy", "The Bot execution context is already active");
|
|
57
|
+
}
|
|
58
|
+
const context = new ActiveBotExecutionContext(handle, command);
|
|
59
|
+
this.#inactiveHandles.delete(handle);
|
|
60
|
+
this.#activeByHandle.set(handle, context);
|
|
61
|
+
return new BotExecutionContextLease(context, () => {
|
|
62
|
+
if (this.#activeByHandle.get(handle) === context) {
|
|
63
|
+
this.#activeByHandle.delete(handle);
|
|
64
|
+
this.#inactiveHandles.add(handle);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
read = (handle) => {
|
|
69
|
+
const context = this.#activeByHandle.get(handle);
|
|
70
|
+
if (context === undefined) {
|
|
71
|
+
if (this.#inactiveHandles.has(handle)) {
|
|
72
|
+
throw new LocalBotAuthorizationError("execution_capability_expired", "The Bot execution capability has expired");
|
|
73
|
+
}
|
|
74
|
+
throw new LocalBotAuthorizationError("execution_context_required", "An active Bot execution context is required");
|
|
75
|
+
}
|
|
76
|
+
if (Date.parse(context.command.executionDeadlineAt) <= this.#now()) {
|
|
77
|
+
throw new LocalBotAuthorizationError("execution_capability_expired", "The Bot execution capability has expired");
|
|
78
|
+
}
|
|
79
|
+
return context;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=bot-execution-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bot-execution-context.js","sourceRoot":"","sources":["../../src/bots/bot-execution-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare class BotMessageCommandError extends Error {
|
|
2
|
+
readonly code: string;
|
|
3
|
+
constructor(code: string, message: string, options?: ErrorOptions);
|
|
4
|
+
}
|
|
5
|
+
export declare function executeBotMessageCommand(arguments_: readonly string[], environment: Readonly<NodeJS.ProcessEnv>, signal: AbortSignal): Promise<string>;
|
|
6
|
+
//# sourceMappingURL=bot-message-command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bot-message-command.d.ts","sourceRoot":"","sources":["../../src/bots/bot-message-command.ts"],"names":[],"mappings":"AAMA,qBAAa,sBAAuB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,YAAY,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,EAIpE;CACJ;AAwID,wBAAsB,wBAAwB,CAC1C,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,EACxC,MAAM,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { createConnection } from "node:net";
|
|
3
|
+
const BOT_IPC_RESPONSE_LIMIT = 64 * 1024;
|
|
4
|
+
const BOT_IPC_TIMEOUT_MILLISECONDS = 20_000;
|
|
5
|
+
export class BotMessageCommandError extends Error {
|
|
6
|
+
code;
|
|
7
|
+
constructor(code, message, options = {}) {
|
|
8
|
+
super(message, options);
|
|
9
|
+
this.code = code;
|
|
10
|
+
this.name = "BotMessageCommandError";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function isRecord(value) {
|
|
14
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
15
|
+
}
|
|
16
|
+
function requiredEnvironment(environment, name) {
|
|
17
|
+
const value = environment[name]?.trim();
|
|
18
|
+
if (value === undefined || value.length === 0) {
|
|
19
|
+
throw new BotMessageCommandError("execution_context_required", "This command is available only inside an active Mobius Bot execution");
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
function option(arguments_, name) {
|
|
24
|
+
const index = arguments_.indexOf(name);
|
|
25
|
+
if (index < 0 || index + 1 >= arguments_.length || arguments_[index + 1]?.startsWith("--") === true) {
|
|
26
|
+
throw new BotMessageCommandError("invalid_request", "Usage: mobius bot message send --target <current|alias> --text <message>");
|
|
27
|
+
}
|
|
28
|
+
const value = arguments_[index + 1];
|
|
29
|
+
if (value === undefined) {
|
|
30
|
+
throw new BotMessageCommandError("invalid_request", "The Bot message option is missing");
|
|
31
|
+
}
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
function validateArguments(arguments_) {
|
|
35
|
+
if (arguments_.length !== 4) {
|
|
36
|
+
throw new BotMessageCommandError("invalid_request", "Usage: mobius bot message send --target <current|alias> --text <message>");
|
|
37
|
+
}
|
|
38
|
+
const names = [arguments_[0], arguments_[2]];
|
|
39
|
+
if (!names.includes("--target") || !names.includes("--text") || names[0] === names[1]) {
|
|
40
|
+
throw new BotMessageCommandError("invalid_request", "Usage: mobius bot message send --target <current|alias> --text <message>");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function decodeResponse(encoded) {
|
|
44
|
+
let value;
|
|
45
|
+
try {
|
|
46
|
+
value = JSON.parse(encoded);
|
|
47
|
+
}
|
|
48
|
+
catch (cause) {
|
|
49
|
+
throw new BotMessageCommandError("bot_service_unavailable", "The local Bot service returned invalid data", {
|
|
50
|
+
cause,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
if (!isRecord(value) || typeof value["ok"] !== "boolean") {
|
|
54
|
+
throw new BotMessageCommandError("bot_service_unavailable", "The local Bot service returned invalid data");
|
|
55
|
+
}
|
|
56
|
+
if (value["ok"] === true && typeof value["outboundMessageId"] === "string") {
|
|
57
|
+
return value["outboundMessageId"];
|
|
58
|
+
}
|
|
59
|
+
const error = value["error"];
|
|
60
|
+
if (value["ok"] === false &&
|
|
61
|
+
isRecord(error) &&
|
|
62
|
+
typeof error["code"] === "string" &&
|
|
63
|
+
typeof error["message"] === "string") {
|
|
64
|
+
throw new BotMessageCommandError(error["code"], error["message"]);
|
|
65
|
+
}
|
|
66
|
+
throw new BotMessageCommandError("bot_service_unavailable", "The local Bot service returned invalid data");
|
|
67
|
+
}
|
|
68
|
+
async function requestLocalBotService(socketPath, payload, signal) {
|
|
69
|
+
signal.throwIfAborted();
|
|
70
|
+
return await new Promise((resolve, reject) => {
|
|
71
|
+
const socket = createConnection(socketPath);
|
|
72
|
+
const chunks = [];
|
|
73
|
+
let length = 0;
|
|
74
|
+
let finished = false;
|
|
75
|
+
const finish = () => {
|
|
76
|
+
socket.removeAllListeners();
|
|
77
|
+
socket.destroy();
|
|
78
|
+
};
|
|
79
|
+
const fail = (error) => {
|
|
80
|
+
if (finished) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
finished = true;
|
|
84
|
+
finish();
|
|
85
|
+
if (error instanceof BotMessageCommandError) {
|
|
86
|
+
reject(error);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
reject(new BotMessageCommandError("execution_context_required", "The active Mobius Bot execution is unavailable", { cause: error }));
|
|
90
|
+
};
|
|
91
|
+
const abort = () => fail(signal.reason);
|
|
92
|
+
socket.setTimeout(BOT_IPC_TIMEOUT_MILLISECONDS, () => {
|
|
93
|
+
fail(new BotMessageCommandError("bot_service_unavailable", "The local Bot service timed out"));
|
|
94
|
+
});
|
|
95
|
+
socket.once("error", fail);
|
|
96
|
+
socket.once("connect", () => socket.end(`${payload}\n`));
|
|
97
|
+
socket.on("data", (chunk) => {
|
|
98
|
+
length += chunk.byteLength;
|
|
99
|
+
if (length > BOT_IPC_RESPONSE_LIMIT) {
|
|
100
|
+
fail(new BotMessageCommandError("bot_service_unavailable", "The local Bot response is too large"));
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
chunks.push(chunk);
|
|
104
|
+
});
|
|
105
|
+
socket.once("end", () => {
|
|
106
|
+
if (finished) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
finished = true;
|
|
110
|
+
signal.removeEventListener("abort", abort);
|
|
111
|
+
try {
|
|
112
|
+
resolve(decodeResponse(Buffer.concat(chunks).toString("utf8")));
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
reject(error);
|
|
116
|
+
}
|
|
117
|
+
finally {
|
|
118
|
+
finish();
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
export async function executeBotMessageCommand(arguments_, environment, signal) {
|
|
125
|
+
validateArguments(arguments_);
|
|
126
|
+
const contextHandle = requiredEnvironment(environment, "MOBIUS_BOT_CONTEXT");
|
|
127
|
+
const socketPath = requiredEnvironment(environment, "MOBIUS_BOT_SOCKET");
|
|
128
|
+
const target = option(arguments_, "--target");
|
|
129
|
+
const text = option(arguments_, "--text");
|
|
130
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/.test(target) || text.trim().length === 0 || text.length > 10_000) {
|
|
131
|
+
throw new BotMessageCommandError("invalid_request", "The Bot outbound message is invalid");
|
|
132
|
+
}
|
|
133
|
+
return await requestLocalBotService(socketPath, JSON.stringify({
|
|
134
|
+
contextHandle,
|
|
135
|
+
idempotencyKey: `cli_${randomUUID()}`,
|
|
136
|
+
target,
|
|
137
|
+
text,
|
|
138
|
+
}), signal);
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=bot-message-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bot-message-command.js","sourceRoot":"","sources":["../../src/bots/bot-message-command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { BotExecutionContextRegistry } from "./bot-execution-context.ts";
|
|
2
|
+
export declare class BotOutboundIpcServer {
|
|
3
|
+
#private;
|
|
4
|
+
constructor(socketPath: string, relayUrl: URL, registry: BotExecutionContextRegistry);
|
|
5
|
+
get socketPath(): string;
|
|
6
|
+
readonly listen: (signal: AbortSignal) => Promise<void>;
|
|
7
|
+
readonly close: () => Promise<void>;
|
|
8
|
+
private readonly abort;
|
|
9
|
+
private readonly accept;
|
|
10
|
+
private readonly handle;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=bot-outbound-ipc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bot-outbound-ipc.d.ts","sourceRoot":"","sources":["../../src/bots/bot-outbound-ipc.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAA6B,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAgHzG,qBAAa,oBAAoB;;IAO7B,YAAY,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,2BAA2B,EAUnF;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,QAAQ,CAAC,MAAM,WAAkB,WAAW,KAAG,OAAO,CAAC,IAAI,CAAC,CAyB1D;IAEF,QAAQ,CAAC,KAAK,QAAa,OAAO,CAAC,IAAI,CAAC,CAmBtC;IAMF,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IAEnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAiDrB;IAEF,OAAO,CAAC,QAAQ,CAAC,MAAM,CA0BrB;CACL"}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { chmod, mkdir, unlink } from "node:fs/promises";
|
|
2
|
+
import { createServer } from "node:net";
|
|
3
|
+
import { dirname, isAbsolute } from "node:path";
|
|
4
|
+
import { MOBIUS_API_PREFIX } from "@moxt-ai/mobius-protocol";
|
|
5
|
+
import { fetch } from "undici";
|
|
6
|
+
import { LocalBotAuthorizationError } from "./local-bot-grant-store.js";
|
|
7
|
+
const BOT_IPC_REQUEST_LIMIT = 32 * 1024;
|
|
8
|
+
const BOT_IPC_TIMEOUT_MILLISECONDS = 20_000;
|
|
9
|
+
const BOT_RELAY_TIMEOUT_MILLISECONDS = 20_000;
|
|
10
|
+
const IDENTIFIER_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/;
|
|
11
|
+
const WINDOWS_NAMED_PIPE_PREFIX = "\\\\.\\pipe\\";
|
|
12
|
+
class BotOutboundIpcRequest {
|
|
13
|
+
contextHandle;
|
|
14
|
+
idempotencyKey;
|
|
15
|
+
target;
|
|
16
|
+
text;
|
|
17
|
+
constructor(contextHandle, idempotencyKey, target, text) {
|
|
18
|
+
this.contextHandle = contextHandle;
|
|
19
|
+
this.idempotencyKey = idempotencyKey;
|
|
20
|
+
this.target = target;
|
|
21
|
+
this.text = text;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function isRecord(value) {
|
|
25
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
26
|
+
}
|
|
27
|
+
function decodeRequest(encoded) {
|
|
28
|
+
let value;
|
|
29
|
+
try {
|
|
30
|
+
value = JSON.parse(encoded);
|
|
31
|
+
}
|
|
32
|
+
catch (cause) {
|
|
33
|
+
throw new LocalBotAuthorizationError("invalid_request", "The local Bot request is invalid", { cause });
|
|
34
|
+
}
|
|
35
|
+
if (!isRecord(value)) {
|
|
36
|
+
throw new LocalBotAuthorizationError("invalid_request", "The local Bot request is invalid");
|
|
37
|
+
}
|
|
38
|
+
const keys = Object.keys(value);
|
|
39
|
+
if (keys.length !== 4 ||
|
|
40
|
+
!keys.every((key) => ["contextHandle", "idempotencyKey", "target", "text"].includes(key))) {
|
|
41
|
+
throw new LocalBotAuthorizationError("invalid_request", "The local Bot request fields are invalid");
|
|
42
|
+
}
|
|
43
|
+
const contextHandle = value["contextHandle"];
|
|
44
|
+
const idempotencyKey = value["idempotencyKey"];
|
|
45
|
+
const target = value["target"];
|
|
46
|
+
const text = value["text"];
|
|
47
|
+
if (typeof contextHandle !== "string" ||
|
|
48
|
+
!/^ctx_[a-zA-Z0-9_-]{43}$/.test(contextHandle) ||
|
|
49
|
+
typeof idempotencyKey !== "string" ||
|
|
50
|
+
!IDENTIFIER_PATTERN.test(idempotencyKey) ||
|
|
51
|
+
typeof target !== "string" ||
|
|
52
|
+
!IDENTIFIER_PATTERN.test(target) ||
|
|
53
|
+
typeof text !== "string" ||
|
|
54
|
+
text.trim().length === 0 ||
|
|
55
|
+
text.length > 10_000) {
|
|
56
|
+
throw new LocalBotAuthorizationError("invalid_request", "The local Bot request is invalid");
|
|
57
|
+
}
|
|
58
|
+
return new BotOutboundIpcRequest(contextHandle, idempotencyKey, target, text);
|
|
59
|
+
}
|
|
60
|
+
function relayEndpoint(relayUrl, context, target) {
|
|
61
|
+
const endpoint = new URL(relayUrl);
|
|
62
|
+
if (endpoint.protocol !== "ws:" && endpoint.protocol !== "wss:") {
|
|
63
|
+
throw new LocalBotAuthorizationError("bot_service_unavailable", "The Mobius Relay URL is invalid");
|
|
64
|
+
}
|
|
65
|
+
endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
|
|
66
|
+
endpoint.search = "";
|
|
67
|
+
const execution = encodeURIComponent(context.command.executionId);
|
|
68
|
+
if (target === "current") {
|
|
69
|
+
context.resolveTarget(target);
|
|
70
|
+
endpoint.pathname = `${MOBIUS_API_PREFIX}/v1/bot-executions/${execution}/reply-messages`;
|
|
71
|
+
return endpoint;
|
|
72
|
+
}
|
|
73
|
+
const deliveryTargetId = context.resolveTarget(target);
|
|
74
|
+
endpoint.pathname = `${MOBIUS_API_PREFIX}/v1/bot-executions/${execution}/delivery-targets/${encodeURIComponent(deliveryTargetId)}/messages`;
|
|
75
|
+
return endpoint;
|
|
76
|
+
}
|
|
77
|
+
function daemonToken(relayUrl) {
|
|
78
|
+
const token = relayUrl.searchParams.get("token") ?? "";
|
|
79
|
+
if (!/^[a-zA-Z0-9_-]{32,256}$/.test(token)) {
|
|
80
|
+
throw new LocalBotAuthorizationError("bot_service_unavailable", "The Runtime credential is unavailable");
|
|
81
|
+
}
|
|
82
|
+
return token;
|
|
83
|
+
}
|
|
84
|
+
async function decodeRelayResponse(response) {
|
|
85
|
+
const encoded = await response.text();
|
|
86
|
+
let value;
|
|
87
|
+
try {
|
|
88
|
+
value = JSON.parse(encoded);
|
|
89
|
+
}
|
|
90
|
+
catch (cause) {
|
|
91
|
+
throw new LocalBotAuthorizationError("bot_service_unavailable", "The Mobius Relay returned invalid data", {
|
|
92
|
+
cause,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
if (response.status === 202 && isRecord(value) && typeof value["outboundMessageId"] === "string") {
|
|
96
|
+
return value["outboundMessageId"];
|
|
97
|
+
}
|
|
98
|
+
if (isRecord(value) && isRecord(value["error"])) {
|
|
99
|
+
const error = value["error"];
|
|
100
|
+
if (typeof error["code"] === "string" && typeof error["message"] === "string") {
|
|
101
|
+
throw new LocalBotAuthorizationError(error["code"], error["message"]);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
throw new LocalBotAuthorizationError("bot_service_unavailable", "The Mobius Relay rejected the Bot action");
|
|
105
|
+
}
|
|
106
|
+
export class BotOutboundIpcServer {
|
|
107
|
+
#registry;
|
|
108
|
+
#relayUrl;
|
|
109
|
+
#server;
|
|
110
|
+
#socketPath;
|
|
111
|
+
#usesFilesystemSocket;
|
|
112
|
+
constructor(socketPath, relayUrl, registry) {
|
|
113
|
+
const usesFilesystemSocket = !socketPath.startsWith(WINDOWS_NAMED_PIPE_PREFIX);
|
|
114
|
+
if (usesFilesystemSocket && !isAbsolute(socketPath)) {
|
|
115
|
+
throw new Error("The Bot IPC path must be absolute");
|
|
116
|
+
}
|
|
117
|
+
this.#registry = registry;
|
|
118
|
+
this.#relayUrl = new URL(relayUrl);
|
|
119
|
+
this.#server = createServer({ allowHalfOpen: true }, (socket) => this.accept(socket));
|
|
120
|
+
this.#socketPath = socketPath;
|
|
121
|
+
this.#usesFilesystemSocket = usesFilesystemSocket;
|
|
122
|
+
}
|
|
123
|
+
get socketPath() {
|
|
124
|
+
return this.#socketPath;
|
|
125
|
+
}
|
|
126
|
+
listen = async (signal) => {
|
|
127
|
+
signal.throwIfAborted();
|
|
128
|
+
if (this.#usesFilesystemSocket) {
|
|
129
|
+
await mkdir(dirname(this.#socketPath), { mode: 0o700, recursive: true });
|
|
130
|
+
await unlink(this.#socketPath).catch((error) => {
|
|
131
|
+
if (!isRecord(error) || error["code"] !== "ENOENT") {
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
await new Promise((resolve, reject) => {
|
|
137
|
+
const fail = (error) => reject(error);
|
|
138
|
+
this.#server.once("error", fail);
|
|
139
|
+
this.#server.listen(this.#socketPath, () => {
|
|
140
|
+
this.#server.removeListener("error", fail);
|
|
141
|
+
resolve();
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
if (this.#usesFilesystemSocket) {
|
|
145
|
+
await chmod(this.#socketPath, 0o600);
|
|
146
|
+
}
|
|
147
|
+
signal.addEventListener("abort", this.abort, { once: true });
|
|
148
|
+
if (signal.aborted) {
|
|
149
|
+
this.abort();
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
close = async () => {
|
|
153
|
+
if (this.#server.listening) {
|
|
154
|
+
await new Promise((resolve, reject) => {
|
|
155
|
+
this.#server.close((error) => {
|
|
156
|
+
if (error === undefined) {
|
|
157
|
+
resolve();
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
reject(error);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
if (this.#usesFilesystemSocket) {
|
|
165
|
+
await unlink(this.#socketPath).catch((error) => {
|
|
166
|
+
if (!isRecord(error) || error["code"] !== "ENOENT") {
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
#abort = () => {
|
|
173
|
+
this.#server.close();
|
|
174
|
+
};
|
|
175
|
+
abort = () => this.#abort();
|
|
176
|
+
accept = (socket) => {
|
|
177
|
+
const chunks = [];
|
|
178
|
+
let length = 0;
|
|
179
|
+
let rejected = false;
|
|
180
|
+
const controller = new AbortController();
|
|
181
|
+
socket.setTimeout(BOT_IPC_TIMEOUT_MILLISECONDS, () => {
|
|
182
|
+
controller.abort(new Error("Bot IPC request timed out"));
|
|
183
|
+
socket.destroy();
|
|
184
|
+
});
|
|
185
|
+
socket.on("data", (chunk) => {
|
|
186
|
+
length += chunk.byteLength;
|
|
187
|
+
if (length > BOT_IPC_REQUEST_LIMIT) {
|
|
188
|
+
rejected = true;
|
|
189
|
+
controller.abort(new Error("Bot IPC request is too large"));
|
|
190
|
+
socket.end(JSON.stringify({
|
|
191
|
+
error: { code: "invalid_request", message: "The local Bot request is too large" },
|
|
192
|
+
ok: false,
|
|
193
|
+
}));
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
chunks.push(chunk);
|
|
197
|
+
});
|
|
198
|
+
socket.once("error", () => controller.abort());
|
|
199
|
+
socket.once("close", () => controller.abort());
|
|
200
|
+
socket.once("end", () => {
|
|
201
|
+
if (rejected) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
void this.handle(Buffer.concat(chunks).toString("utf8").trim(), controller.signal).then((outboundMessageId) => {
|
|
205
|
+
if (!socket.destroyed) {
|
|
206
|
+
socket.end(JSON.stringify({ ok: true, outboundMessageId }));
|
|
207
|
+
}
|
|
208
|
+
}, (error) => {
|
|
209
|
+
if (socket.destroyed) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const code = error instanceof LocalBotAuthorizationError ? error.code : "bot_service_unavailable";
|
|
213
|
+
const message = error instanceof LocalBotAuthorizationError
|
|
214
|
+
? error.message
|
|
215
|
+
: "The local Bot action could not be completed";
|
|
216
|
+
socket.end(JSON.stringify({ error: { code, message }, ok: false }));
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
};
|
|
220
|
+
handle = async (encoded, signal) => {
|
|
221
|
+
const request = decodeRequest(encoded);
|
|
222
|
+
const context = this.#registry.read(request.contextHandle);
|
|
223
|
+
const timeout = AbortSignal.timeout(BOT_RELAY_TIMEOUT_MILLISECONDS);
|
|
224
|
+
const requestSignal = AbortSignal.any([signal, timeout]);
|
|
225
|
+
let response;
|
|
226
|
+
try {
|
|
227
|
+
response = await fetch(relayEndpoint(this.#relayUrl, context, request.target), {
|
|
228
|
+
body: JSON.stringify({ idempotencyKey: request.idempotencyKey, text: request.text }),
|
|
229
|
+
headers: {
|
|
230
|
+
authorization: `Bearer ${daemonToken(this.#relayUrl)}`,
|
|
231
|
+
"content-type": "application/json",
|
|
232
|
+
"x-mobius-bot-execution-capability": context.command.executionCapabilitySecret,
|
|
233
|
+
},
|
|
234
|
+
method: "POST",
|
|
235
|
+
signal: requestSignal,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
catch (cause) {
|
|
239
|
+
signal.throwIfAborted();
|
|
240
|
+
throw new LocalBotAuthorizationError(timeout.aborted ? "bot_service_timeout" : "bot_service_unavailable", timeout.aborted ? "The Mobius Bot action timed out" : "The Mobius Relay is unavailable", { cause });
|
|
241
|
+
}
|
|
242
|
+
return await decodeRelayResponse(response);
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=bot-outbound-ipc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bot-outbound-ipc.js","sourceRoot":"","sources":["../../src/bots/bot-outbound-ipc.ts"],"names":[],"mappings":"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"}
|