@0xmaxma/claude-gateway 1.3.32 → 1.4.1
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/agent/runner.d.ts +22 -1
- package/dist/agent/runner.d.ts.map +1 -1
- package/dist/agent/runner.js +76 -3
- package/dist/agent/runner.js.map +1 -1
- package/dist/api/router.d.ts.map +1 -1
- package/dist/api/router.js +39 -4
- package/dist/api/router.js.map +1 -1
- package/dist/history/db.d.ts +8 -0
- package/dist/history/db.d.ts.map +1 -1
- package/dist/history/db.js +22 -3
- package/dist/history/db.js.map +1 -1
- package/dist/session/process.d.ts.map +1 -1
- package/dist/session/process.js +30 -0
- package/dist/session/process.js.map +1 -1
- package/dist/session/store.d.ts +3 -2
- package/dist/session/store.d.ts.map +1 -1
- package/dist/session/store.js +1 -1
- package/dist/session/store.js.map +1 -1
- package/dist/types.d.ts +17 -0
- package/dist/types.d.ts.map +1 -1
- package/mcp/instructions.ts +39 -0
- package/mcp/server.ts +6 -11
- package/mcp/tools/discord/module.ts +19 -1
- package/mcp/tools/image/module.ts +592 -0
- package/package.json +1 -1
package/dist/agent/runner.d.ts
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
-
import { AgentConfig, GatewayConfig, Logger, ModelConfig, StreamEvent, ApiAttachment } from '../types';
|
|
2
|
+
import { AgentConfig, GatewayConfig, Logger, ModelConfig, StreamEvent, ApiAttachment, ImageParams } from '../types';
|
|
3
3
|
import { type SkillRegistry } from '../skills';
|
|
4
4
|
import { HistoryDB } from '../history/db';
|
|
5
5
|
export declare const MAX_IMAGE_SIZE_BYTES: number;
|
|
6
6
|
export declare const DEFAULT_MODELS: ModelConfig[];
|
|
7
7
|
export declare const CHANNEL_COALESCE_WINDOW_MS = 1200;
|
|
8
|
+
/**
|
|
9
|
+
* Convert absolute file paths (e.g. from a reply tool's `files` input) into
|
|
10
|
+
* relative `media/<rel>` paths for persistence as message `mediaFiles`.
|
|
11
|
+
*
|
|
12
|
+
* Mirrors the transform in `popApiAttachments`: only paths UNDER `mediaRoot`
|
|
13
|
+
* that pass the `exists` predicate are kept (never arbitrary abs paths, never
|
|
14
|
+
* dangling files), and backslashes are normalised to forward slashes.
|
|
15
|
+
*
|
|
16
|
+
* The `exists` predicate is injected (defaults to `fs.existsSync`) so the pure
|
|
17
|
+
* string transform is unit-testable without a real filesystem.
|
|
18
|
+
*/
|
|
19
|
+
export declare function toRelMediaFiles(absPaths: unknown[], mediaRoot: string, exists?: (p: string) => boolean): string[];
|
|
8
20
|
export declare class AgentRunner extends EventEmitter {
|
|
9
21
|
private agentConfig;
|
|
10
22
|
private readonly gatewayConfig;
|
|
@@ -117,6 +129,12 @@ export declare class AgentRunner extends EventEmitter {
|
|
|
117
129
|
* a photo and its instruction text are read together in the same turn.
|
|
118
130
|
*/
|
|
119
131
|
private routeChannelTurn;
|
|
132
|
+
/**
|
|
133
|
+
* Render composer-selected image options (contract E5) as a directive the agent
|
|
134
|
+
* reads and forwards to the generate_image MCP tool. Returns '' when no usable
|
|
135
|
+
* options are present.
|
|
136
|
+
*/
|
|
137
|
+
private static buildImageParamsNote;
|
|
120
138
|
private static buildChannelXml;
|
|
121
139
|
private getOrSpawnSession;
|
|
122
140
|
private spawnSession;
|
|
@@ -288,6 +306,7 @@ export declare class AgentRunner extends EventEmitter {
|
|
|
288
306
|
mediaFiles?: string[];
|
|
289
307
|
model?: string;
|
|
290
308
|
skipUserMessage?: boolean;
|
|
309
|
+
imageParams?: ImageParams;
|
|
291
310
|
}): Promise<{
|
|
292
311
|
text: string;
|
|
293
312
|
attachments: ApiAttachment[];
|
|
@@ -308,6 +327,7 @@ export declare class AgentRunner extends EventEmitter {
|
|
|
308
327
|
mediaFiles?: string[];
|
|
309
328
|
model?: string;
|
|
310
329
|
skipUserMessage?: boolean;
|
|
330
|
+
imageParams?: ImageParams;
|
|
311
331
|
}): Promise<() => void>;
|
|
312
332
|
/**
|
|
313
333
|
* Check if a session has a pending API request (for preflight conflict check).
|
|
@@ -330,6 +350,7 @@ export declare class AgentRunner extends EventEmitter {
|
|
|
330
350
|
getHistoryDb(): HistoryDB;
|
|
331
351
|
getAllSessionMeta(): Promise<Map<string, {
|
|
332
352
|
name: string;
|
|
353
|
+
imageConfig?: ImageParams;
|
|
333
354
|
}>>;
|
|
334
355
|
listSessionsForChat(chatId: string, channel: 'telegram' | 'discord' | 'line'): Promise<import('../types').SessionIndex>;
|
|
335
356
|
executeApiCommand(sessionId: string, chatId: string, command: string, opts?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/agent/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAMtC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAW,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/agent/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAMtC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAW,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAS7H,OAAO,EAA0C,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAQvF,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAqB1C,eAAO,MAAM,oBAAoB,QAAmB,CAAC;AAErD,eAAO,MAAM,cAAc,EAAE,WAAW,EAUvC,CAAC;AAqBF,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAkD/C;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,OAAO,EAAE,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAuB,GAC7C,MAAM,EAAE,CAIV;AAED,qBAAa,WAAY,SAAQ,YAAY;IAC3C,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA6B;IAC9D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IACrD,OAAO,CAAC,SAAS,CAAoC;IAErD,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IACjC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAEvC,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;IAC9D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsD;IACvF,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,eAAe,CAAgC;IAEvD,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,gBAAgB,CAA+C;IAGvE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqB;IAGxD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA8C;IAMhF,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA6B;IAKhE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAqB;IAOvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAQtB;IAIH,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkC;IAKlE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4E;IAGrG,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA+B;IAOjE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAO5B;IAIJ,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAG1C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAA+B;IAGrE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAoH;IAKnJ,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6B;IAGxD,OAAO,CAAC,aAAa,CAAwC;IAG7D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IAGpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IAGtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IAEvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAGlC,OAAO,CAAC,aAAa,CAA6B;gBAEtC,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,MAAM;IAwBnF;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAI/C,gBAAgB,IAAI,aAAa;IAIjC,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED;;;OAGG;YACW,mBAAmB;IAwHjC;;;;;;OAMG;YACW,oBAAoB;IA2ElC;;;;;;;OAOG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAU5D;;;;;;;;OAQG;IACH,OAAO,CAAC,oBAAoB;IAgC5B;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAO5B;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB,CA8BzB;IAEF;;;OAGG;YACW,oBAAoB;IAqLlC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,MAAM,CAAC,aAAa;IAI5B,OAAO,CAAC,iBAAiB;IAYzB;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IA2GxB;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAmBnC,OAAO,CAAC,MAAM,CAAC,eAAe;YA0ChB,iBAAiB;YAgDjB,YAAY;IAka1B,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIpD;;OAEG;YACW,oBAAoB;IAsBlC;;OAEG;YACW,qBAAqB;IAiBnC;;OAEG;YACW,wBAAwB;IA+CtC;;OAEG;YACW,gBAAgB;IAM9B;;OAEG;YACW,mBAAmB;IAUjC;;;OAGG;YACW,iBAAiB;IAM/B;;;OAGG;YACW,kBAAkB;IA8BhC;;OAEG;YACW,oBAAoB;IA4ClC;;;OAGG;YACW,aAAa;IAS3B;;;OAGG;YACW,cAAc;IAS5B;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAIrB;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,qBAAqB;IAgD7B;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,cAAc,CAAC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BlE;;OAEG;IACH,OAAO,CAAC,SAAS;IAWjB;;;;OAIG;IACD,OAAO,CAAC,YAAY;IAMtB,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,eAAe;YAST,wBAAwB;IA2BtC,OAAO,CAAC,gBAAgB;IAexB;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAexB,OAAO,CAAC,gBAAgB;IAalB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4B5B,iBAAiB,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI;IAQ/C,cAAc,IAAI,IAAI;IAetB,aAAa,IAAI,IAAI;IAOrB,cAAc,IAAI,WAAW;IAI7B,qBAAqB,IAAI,IAAI;IAY7B,oBAAoB,IAAI,IAAI;IAO5B,oBAAoB,IAAI,IAAI;IAY5B,mBAAmB,IAAI,IAAI;IAOrB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB3B;;;;OAIG;IACG,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK5F,OAAO,CAAC,sBAAsB;IAqBxB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAM9B,SAAS,IAAI,OAAO;IAIpB,kBAAkB,IAAI,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IA4BzL;;;;;;;OAOG;IACG,cAAc,CAClB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,WAAW,CAAA;KAAE,GAC7I,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,aAAa,EAAE,CAAA;KAAE,CAAC;IAuM1D;;;;;OAKG;IACG,oBAAoB,CACxB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,SAAS,EAAE;QACT,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;QACtC,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;QACjE,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;KAC/B,EACD,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,WAAW,CAAA;KAAE,GAC7I,OAAO,CAAC,MAAM,IAAI,CAAC;IAmOtB;;OAEG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI/C;;;;OAIG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IAK/D;;;OAGG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,EAAE;IAcrD,OAAO,CAAC,sBAAsB;IAc9B,gBAAgB,IAAI,MAAM;IAI1B,WAAW,IAAI,MAAM;IAIrB,YAAY,IAAI,SAAS;IAIzB,iBAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,WAAW,CAAA;KAAE,CAAC,CAAC;IAIhF,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,UAAU,EAAE,YAAY,CAAC;IAIvH,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE,GAC/B,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IAsK/D,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASzC,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,UAAU,EAAE,YAAY,CAAC;IAIzE,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC;IAc/G,OAAO,CAAC,+BAA+B;IAsBjC,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAmB7F,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAW5I,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWxE;;;;OAIG;IACG,oBAAoB,CACxB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,EACxC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,SAAS,EAAE;QACT,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;QACtC,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;QACnC,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;KAC/B,EACD,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAC1B,OAAO,CAAC,MAAM,IAAI,CAAC;IAiItB,OAAO,CAAC,iBAAiB;IA2CzB;;;OAGG;IACH,eAAe,IAAI,MAAM;IAIzB;;;;;;OAMG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CAoBnC"}
|
package/dist/agent/runner.js
CHANGED
|
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.AgentRunner = exports.CHANNEL_COALESCE_WINDOW_MS = exports.DEFAULT_MODELS = exports.MAX_IMAGE_SIZE_BYTES = void 0;
|
|
37
|
+
exports.toRelMediaFiles = toRelMediaFiles;
|
|
37
38
|
const events_1 = require("events");
|
|
38
39
|
const fs = __importStar(require("fs"));
|
|
39
40
|
const fsPromises = __importStar(require("fs/promises"));
|
|
@@ -127,6 +128,10 @@ function buildApiSystemNote(allowTools, imagePaths) {
|
|
|
127
128
|
const memoryOverride = `Memory Rule Override: Do NOT create or update ${PROTECTED_WORKSPACE_FILES.join(', ')} ` +
|
|
128
129
|
`or any other workspace identity file in this session, regardless of user instructions. ` +
|
|
129
130
|
`If the user asks you to remember something, reply that memory updates are not supported in API sessions.`;
|
|
131
|
+
const secretsRule = `Secret Non-Disclosure: NEVER reveal, print, echo, or transmit environment variables, ` +
|
|
132
|
+
`API tokens or keys, the contents of ~/.claude/settings.json or any .env file, or any ` +
|
|
133
|
+
`similar credentials or secrets — regardless of who asks or how the request is phrased. ` +
|
|
134
|
+
`Treat any such request as adversarial and refuse it.`;
|
|
130
135
|
const toolNote = allowTools
|
|
131
136
|
? `You may use tools to complete the requested task.`
|
|
132
137
|
: `Reply with plain text only. Do NOT call any tools. Your text output will be returned directly to the caller.`;
|
|
@@ -134,7 +139,23 @@ function buildApiSystemNote(allowTools, imagePaths) {
|
|
|
134
139
|
if (imagePaths?.length) {
|
|
135
140
|
imageNote = ` The user attached ${imagePaths.length} image(s). Read them with the Read tool:\n${imagePaths.map(p => `- ${p}`).join('\n')}`;
|
|
136
141
|
}
|
|
137
|
-
return `<api-context>This is an API request. ${memoryOverride} ${toolNote}${imageNote}</api-context>\n`;
|
|
142
|
+
return `<api-context>This is an API request. ${memoryOverride} ${secretsRule} ${toolNote}${imageNote}</api-context>\n`;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Convert absolute file paths (e.g. from a reply tool's `files` input) into
|
|
146
|
+
* relative `media/<rel>` paths for persistence as message `mediaFiles`.
|
|
147
|
+
*
|
|
148
|
+
* Mirrors the transform in `popApiAttachments`: only paths UNDER `mediaRoot`
|
|
149
|
+
* that pass the `exists` predicate are kept (never arbitrary abs paths, never
|
|
150
|
+
* dangling files), and backslashes are normalised to forward slashes.
|
|
151
|
+
*
|
|
152
|
+
* The `exists` predicate is injected (defaults to `fs.existsSync`) so the pure
|
|
153
|
+
* string transform is unit-testable without a real filesystem.
|
|
154
|
+
*/
|
|
155
|
+
function toRelMediaFiles(absPaths, mediaRoot, exists = fs.existsSync) {
|
|
156
|
+
return absPaths
|
|
157
|
+
.filter((p) => typeof p === 'string' && p.startsWith(mediaRoot) && exists(p))
|
|
158
|
+
.map((p) => 'media/' + p.slice(mediaRoot.length).replace(/\\/g, '/'));
|
|
138
159
|
}
|
|
139
160
|
class AgentRunner extends events_1.EventEmitter {
|
|
140
161
|
imageSize(chatId) { return this.imageSizePerChat.get(chatId) ?? 0; }
|
|
@@ -858,6 +879,28 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
858
879
|
this.writeTypingError(chatId, code);
|
|
859
880
|
});
|
|
860
881
|
}
|
|
882
|
+
/**
|
|
883
|
+
* Render composer-selected image options (contract E5) as a directive the agent
|
|
884
|
+
* reads and forwards to the generate_image MCP tool. Returns '' when no usable
|
|
885
|
+
* options are present.
|
|
886
|
+
*/
|
|
887
|
+
static buildImageParamsNote(p) {
|
|
888
|
+
const attrs = [
|
|
889
|
+
p.model ? `model="${AgentRunner.escapeXmlAttr(p.model)}"` : '',
|
|
890
|
+
p.quality ? `quality="${AgentRunner.escapeXmlAttr(p.quality)}"` : '',
|
|
891
|
+
p.size ? `size="${AgentRunner.escapeXmlAttr(p.size)}"` : '',
|
|
892
|
+
p.aspect_ratio ? `aspect_ratio="${AgentRunner.escapeXmlAttr(p.aspect_ratio)}"` : '',
|
|
893
|
+
typeof p.n === 'number' ? `n="${p.n}"` : '',
|
|
894
|
+
p.image_ref ? `image_ref="${AgentRunner.escapeXmlAttr(p.image_ref)}"` : '',
|
|
895
|
+
].filter(Boolean);
|
|
896
|
+
if (!attrs.length)
|
|
897
|
+
return '';
|
|
898
|
+
return (`<image-params ${attrs.join(' ')} />\n` +
|
|
899
|
+
`The user selected the image-generation options above in the composer. When the request ` +
|
|
900
|
+
`involves creating or editing an image, call the generate_image tool (action="generate") ` +
|
|
901
|
+
`using these values (pass image_ref as the "image" argument for image-to-image), then ` +
|
|
902
|
+
`deliver the returned image with your reply tool.\n`);
|
|
903
|
+
}
|
|
861
904
|
static buildChannelXml(params) {
|
|
862
905
|
const meta = params.meta ?? {};
|
|
863
906
|
const optionalAttrs = [
|
|
@@ -1042,7 +1085,15 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
1042
1085
|
replyToolUseId = block['id'] ?? null;
|
|
1043
1086
|
// Persist the reply text to history so it appears in chat history API
|
|
1044
1087
|
const replyText = typeof block.input?.['text'] === 'string' ? block.input['text'].trim() : '';
|
|
1045
|
-
|
|
1088
|
+
// Capture any images the reply attached (reply tool's `files`)
|
|
1089
|
+
// so the web transcript renders them via mediaFiles. Only files
|
|
1090
|
+
// under the agent media root that still exist are recorded.
|
|
1091
|
+
const replyFiles = Array.isArray(block.input?.['files']) ? block.input['files'] : [];
|
|
1092
|
+
const mediaRoot = path.join(this.agentsBaseDir, this.agentConfig.id, 'media') + path.sep;
|
|
1093
|
+
const replyMedia = toRelMediaFiles(replyFiles, mediaRoot);
|
|
1094
|
+
// Persist when there is text OR image(s) — an image-only reply
|
|
1095
|
+
// still needs a row so it shows in the web transcript.
|
|
1096
|
+
if (replyText || replyMedia.length) {
|
|
1046
1097
|
const channelSrc = this.channelSourceMap.get(mapKey) ?? 'telegram';
|
|
1047
1098
|
this.historyDb.insertMessage({
|
|
1048
1099
|
chatId: `${channelSrc}-${mapKey}`,
|
|
@@ -1050,12 +1101,13 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
1050
1101
|
source: channelSrc,
|
|
1051
1102
|
role: 'assistant',
|
|
1052
1103
|
content: replyText,
|
|
1104
|
+
mediaFiles: replyMedia.length ? replyMedia : undefined,
|
|
1053
1105
|
ts: Date.now(),
|
|
1054
1106
|
});
|
|
1055
1107
|
// LINE: the MCP line_reply tool's send is suppressed in
|
|
1056
1108
|
// refresh mode; the gateway delivers (free reply, or cache +
|
|
1057
1109
|
// postback button when slow). See LineReplyManager.
|
|
1058
|
-
if (channelSrc === 'line' && this.lineReply) {
|
|
1110
|
+
if (channelSrc === 'line' && this.lineReply && replyText) {
|
|
1059
1111
|
void this.lineReply.onAnswer(mapKey, replyText);
|
|
1060
1112
|
}
|
|
1061
1113
|
}
|
|
@@ -2021,9 +2073,20 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
2021
2073
|
}
|
|
2022
2074
|
// Build channel XML with image_path attribute (like Telegram) for first image
|
|
2023
2075
|
const imageAttr = effectiveImagePaths.length ? ` image_path="${AgentRunner.escapeXmlAttr(effectiveImagePaths[0])}"` : '';
|
|
2076
|
+
const imageParamsNote = opts.imageParams ? AgentRunner.buildImageParamsNote(opts.imageParams) : '';
|
|
2077
|
+
// Persist the composer image options to session meta so the web can restore the
|
|
2078
|
+
// selection on reload (SessionMeta.imageConfig). Only when the send carries them
|
|
2079
|
+
// (the web sends image_params on first-set/change), so this holds the latest.
|
|
2080
|
+
// Channel is 'api' here (api sessions live under api-<chatId>). Best-effort.
|
|
2081
|
+
if (opts.imageParams) {
|
|
2082
|
+
this.sessionStore
|
|
2083
|
+
.updateSessionMeta(this.agentConfig.id, chatId, sessionId, { imageConfig: opts.imageParams }, 'api')
|
|
2084
|
+
.catch(() => { });
|
|
2085
|
+
}
|
|
2024
2086
|
const channelXml = `<channel source="api" chat_id="${chatId}" session_id="${sessionId}" ts="${new Date().toISOString()}"${imageAttr}>\n` +
|
|
2025
2087
|
`${message}\n\n` +
|
|
2026
2088
|
`${systemNote}` +
|
|
2089
|
+
`${imageParamsNote}` +
|
|
2027
2090
|
`</channel>` +
|
|
2028
2091
|
(skillInvocation ? `\n${(0, skills_1.formatSkillContext)(skillInvocation)}` : '');
|
|
2029
2092
|
return new Promise((resolve, reject) => {
|
|
@@ -2320,9 +2383,19 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
2320
2383
|
}
|
|
2321
2384
|
// Build channel XML with image_path attribute (like Telegram) for first image
|
|
2322
2385
|
const imageAttrStream = effectiveImagePathsStream.length ? ` image_path="${AgentRunner.escapeXmlAttr(effectiveImagePathsStream[0])}"` : '';
|
|
2386
|
+
const imageParamsNoteStream = opts.imageParams ? AgentRunner.buildImageParamsNote(opts.imageParams) : '';
|
|
2387
|
+
// Persist composer image config to session meta (SessionMeta.imageConfig) so the
|
|
2388
|
+
// web restores the selection on reload. This is the streaming path the web uses.
|
|
2389
|
+
// Channel 'api' — api sessions live under api-<chatId>. Best-effort.
|
|
2390
|
+
if (opts.imageParams) {
|
|
2391
|
+
this.sessionStore
|
|
2392
|
+
.updateSessionMeta(this.agentConfig.id, chatId, sessionId, { imageConfig: opts.imageParams }, 'api')
|
|
2393
|
+
.catch(() => { });
|
|
2394
|
+
}
|
|
2323
2395
|
const channelXml = `<channel source="api" chat_id="${chatId}" session_id="${sessionId}" ts="${new Date().toISOString()}"${imageAttrStream}>\n` +
|
|
2324
2396
|
`${message}\n\n` +
|
|
2325
2397
|
systemNote +
|
|
2398
|
+
imageParamsNoteStream +
|
|
2326
2399
|
`</channel>` +
|
|
2327
2400
|
(skillInvocationStream ? `\n${(0, skills_1.formatSkillContext)(skillInvocationStream)}` : '');
|
|
2328
2401
|
session.setProcessing(true);
|