@parall/agent-core 1.13.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/dispatch-adapter.d.ts +79 -0
- package/dist/dispatch-adapter.d.ts.map +1 -0
- package/dist/dispatch-adapter.js +1 -0
- package/dist/event-format.d.ts +4 -0
- package/dist/event-format.d.ts.map +1 -0
- package/dist/event-format.js +42 -0
- package/dist/gateway-base.d.ts +69 -0
- package/dist/gateway-base.d.ts.map +1 -0
- package/dist/gateway-base.js +865 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/routing.d.ts +25 -0
- package/dist/routing.d.ts.map +1 -0
- package/dist/routing.js +29 -0
- package/dist/session-state.d.ts +17 -0
- package/dist/session-state.d.ts.map +1 -0
- package/dist/session-state.js +54 -0
- package/dist/types.d.ts +35 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +35 -0
- package/src/dispatch-adapter.ts +66 -0
- package/src/event-format.ts +40 -0
- package/src/gateway-base.ts +989 -0
- package/src/index.ts +6 -0
- package/src/routing.ts +47 -0
- package/src/session-state.ts +69 -0
- package/src/types.ts +32 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DispatchState, ParallEvent } from "./types.js";
|
|
2
|
+
/** Where an inbound event should be routed. */
|
|
3
|
+
export type TriggerDisposition = {
|
|
4
|
+
action: "main";
|
|
5
|
+
} | {
|
|
6
|
+
action: "buffer-main";
|
|
7
|
+
} | {
|
|
8
|
+
action: "buffer-fork";
|
|
9
|
+
forkKey: string;
|
|
10
|
+
} | {
|
|
11
|
+
action: "new-fork";
|
|
12
|
+
};
|
|
13
|
+
/** Pluggable strategy for routing triggers when main session is busy. */
|
|
14
|
+
export type RoutingStrategy = (event: ParallEvent, state: DispatchState) => TriggerDisposition;
|
|
15
|
+
/**
|
|
16
|
+
* Default routing strategy:
|
|
17
|
+
* - Same target as main → buffer-main (strict per-target serial ordering)
|
|
18
|
+
* - Active fork for same target → buffer into that fork
|
|
19
|
+
* - Too many forks → buffer-main (backpressure)
|
|
20
|
+
* - Otherwise → create a new fork
|
|
21
|
+
*/
|
|
22
|
+
export declare const defaultRoutingStrategy: RoutingStrategy;
|
|
23
|
+
/** Route an inbound event based on current dispatch state. */
|
|
24
|
+
export declare function routeTrigger(event: ParallEvent, state: DispatchState, strategy?: RoutingStrategy): TriggerDisposition;
|
|
25
|
+
//# sourceMappingURL=routing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../src/routing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE7D,+CAA+C;AAC/C,MAAM,MAAM,kBAAkB,GAC1B;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,GACzB;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC;AAE3B,yEAAyE;AACzE,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,aAAa,KAAK,kBAAkB,CAAC;AAI/F;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,EAAE,eAapC,CAAC;AAEF,8DAA8D;AAC9D,wBAAgB,YAAY,CAC1B,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,aAAa,EACpB,QAAQ,GAAE,eAAwC,GACjD,kBAAkB,CAKpB"}
|
package/dist/routing.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const MAX_CONCURRENT_FORKS = 20;
|
|
2
|
+
/**
|
|
3
|
+
* Default routing strategy:
|
|
4
|
+
* - Same target as main → buffer-main (strict per-target serial ordering)
|
|
5
|
+
* - Active fork for same target → buffer into that fork
|
|
6
|
+
* - Too many forks → buffer-main (backpressure)
|
|
7
|
+
* - Otherwise → create a new fork
|
|
8
|
+
*/
|
|
9
|
+
export const defaultRoutingStrategy = (event, state) => {
|
|
10
|
+
if (state.mainCurrentTargetId === event.targetId) {
|
|
11
|
+
return { action: "buffer-main" };
|
|
12
|
+
}
|
|
13
|
+
const existingForkKey = state.activeForks.get(event.targetId);
|
|
14
|
+
if (existingForkKey)
|
|
15
|
+
return { action: "buffer-fork", forkKey: existingForkKey };
|
|
16
|
+
if (state.activeForks.size >= MAX_CONCURRENT_FORKS) {
|
|
17
|
+
return { action: "buffer-main" };
|
|
18
|
+
}
|
|
19
|
+
return { action: "new-fork" };
|
|
20
|
+
};
|
|
21
|
+
/** Route an inbound event based on current dispatch state. */
|
|
22
|
+
export function routeTrigger(event, state, strategy = defaultRoutingStrategy) {
|
|
23
|
+
const existingForkKey = state.activeForks.get(event.targetId);
|
|
24
|
+
if (existingForkKey)
|
|
25
|
+
return { action: "buffer-fork", forkKey: existingForkKey };
|
|
26
|
+
if (!state.mainDispatching)
|
|
27
|
+
return { action: "main" };
|
|
28
|
+
return strategy(event, state);
|
|
29
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare function setSessionChatId(sessionKey: string, chatId: string): void;
|
|
2
|
+
export declare function getSessionChatId(sessionKey: string): string | undefined;
|
|
3
|
+
export declare function setSessionMessageId(sessionKey: string, messageId: string): void;
|
|
4
|
+
export declare function getSessionMessageId(sessionKey: string): string | undefined;
|
|
5
|
+
export declare function clearSessionMessageId(sessionKey: string): void;
|
|
6
|
+
/** Snapshot the message ID at dispatch time — immune to later session-level overwrites. */
|
|
7
|
+
export declare function setDispatchMessageId(sessionKey: string, messageId: string): void;
|
|
8
|
+
/** Read the dispatch-time snapshot. Prefer this over getSessionMessageId for provenance. */
|
|
9
|
+
export declare function getDispatchMessageId(sessionKey: string): string | undefined;
|
|
10
|
+
export declare function clearDispatchMessageId(sessionKey: string): void;
|
|
11
|
+
export declare function setDispatchGroupKey(sessionKey: string, groupKey: string): void;
|
|
12
|
+
export declare function getDispatchGroupKey(sessionKey: string): string | undefined;
|
|
13
|
+
export declare function clearDispatchGroupKey(sessionKey: string): void;
|
|
14
|
+
export declare function setDispatchNoReply(sessionKey: string, noReply: boolean): void;
|
|
15
|
+
export declare function getDispatchNoReply(sessionKey: string): boolean;
|
|
16
|
+
export declare function clearDispatchNoReply(sessionKey: string): void;
|
|
17
|
+
//# sourceMappingURL=session-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-state.d.ts","sourceRoot":"","sources":["../src/session-state.ts"],"names":[],"mappings":"AAYA,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAElE;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvE;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAExE;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE1E;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,QAEvD;AAED,2FAA2F;AAC3F,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAEzE;AAED,4FAA4F;AAC5F,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE3E;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,QAExD;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,QAEvE;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE1E;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,QAEvD;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,QAEtE;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,QAEtD"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
function normalizeSessionKey(sessionKey) {
|
|
2
|
+
return sessionKey.toLowerCase();
|
|
3
|
+
}
|
|
4
|
+
// Session key → original chat ID mapping.
|
|
5
|
+
// Runtime session keys may be normalized to lowercase, but Parall IDs are case-sensitive.
|
|
6
|
+
const sessionChatIdMap = new Map();
|
|
7
|
+
const sessionMessageIdMap = new Map();
|
|
8
|
+
const dispatchMessageIdMap = new Map();
|
|
9
|
+
const dispatchGroupKeyMap = new Map();
|
|
10
|
+
const dispatchNoReplyMap = new Map();
|
|
11
|
+
export function setSessionChatId(sessionKey, chatId) {
|
|
12
|
+
sessionChatIdMap.set(normalizeSessionKey(sessionKey), chatId);
|
|
13
|
+
}
|
|
14
|
+
export function getSessionChatId(sessionKey) {
|
|
15
|
+
return sessionChatIdMap.get(normalizeSessionKey(sessionKey));
|
|
16
|
+
}
|
|
17
|
+
export function setSessionMessageId(sessionKey, messageId) {
|
|
18
|
+
sessionMessageIdMap.set(normalizeSessionKey(sessionKey), messageId);
|
|
19
|
+
}
|
|
20
|
+
export function getSessionMessageId(sessionKey) {
|
|
21
|
+
return sessionMessageIdMap.get(normalizeSessionKey(sessionKey));
|
|
22
|
+
}
|
|
23
|
+
export function clearSessionMessageId(sessionKey) {
|
|
24
|
+
sessionMessageIdMap.delete(normalizeSessionKey(sessionKey));
|
|
25
|
+
}
|
|
26
|
+
/** Snapshot the message ID at dispatch time — immune to later session-level overwrites. */
|
|
27
|
+
export function setDispatchMessageId(sessionKey, messageId) {
|
|
28
|
+
dispatchMessageIdMap.set(normalizeSessionKey(sessionKey), messageId);
|
|
29
|
+
}
|
|
30
|
+
/** Read the dispatch-time snapshot. Prefer this over getSessionMessageId for provenance. */
|
|
31
|
+
export function getDispatchMessageId(sessionKey) {
|
|
32
|
+
return dispatchMessageIdMap.get(normalizeSessionKey(sessionKey));
|
|
33
|
+
}
|
|
34
|
+
export function clearDispatchMessageId(sessionKey) {
|
|
35
|
+
dispatchMessageIdMap.delete(normalizeSessionKey(sessionKey));
|
|
36
|
+
}
|
|
37
|
+
export function setDispatchGroupKey(sessionKey, groupKey) {
|
|
38
|
+
dispatchGroupKeyMap.set(normalizeSessionKey(sessionKey), groupKey);
|
|
39
|
+
}
|
|
40
|
+
export function getDispatchGroupKey(sessionKey) {
|
|
41
|
+
return dispatchGroupKeyMap.get(normalizeSessionKey(sessionKey));
|
|
42
|
+
}
|
|
43
|
+
export function clearDispatchGroupKey(sessionKey) {
|
|
44
|
+
dispatchGroupKeyMap.delete(normalizeSessionKey(sessionKey));
|
|
45
|
+
}
|
|
46
|
+
export function setDispatchNoReply(sessionKey, noReply) {
|
|
47
|
+
dispatchNoReplyMap.set(normalizeSessionKey(sessionKey), noReply);
|
|
48
|
+
}
|
|
49
|
+
export function getDispatchNoReply(sessionKey) {
|
|
50
|
+
return dispatchNoReplyMap.get(normalizeSessionKey(sessionKey)) ?? false;
|
|
51
|
+
}
|
|
52
|
+
export function clearDispatchNoReply(sessionKey) {
|
|
53
|
+
dispatchNoReplyMap.delete(normalizeSessionKey(sessionKey));
|
|
54
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Result from a completed fork dispatch, to be injected into main session's next turn. */
|
|
2
|
+
export type ForkResult = {
|
|
3
|
+
forkSessionKey: string;
|
|
4
|
+
sourceEvent: {
|
|
5
|
+
type: string;
|
|
6
|
+
targetId: string;
|
|
7
|
+
summary: string;
|
|
8
|
+
};
|
|
9
|
+
actions: string[];
|
|
10
|
+
};
|
|
11
|
+
/** Mutable dispatch state for the orchestrator gateway. */
|
|
12
|
+
export type DispatchState = {
|
|
13
|
+
mainDispatching: boolean;
|
|
14
|
+
mainCurrentTargetId?: string;
|
|
15
|
+
activeForks: Map<string, string>;
|
|
16
|
+
pendingForkResults: ForkResult[];
|
|
17
|
+
mainBuffer: ParallEvent[];
|
|
18
|
+
};
|
|
19
|
+
/** Normalized inbound event from Parall. */
|
|
20
|
+
export type ParallEvent = {
|
|
21
|
+
type: "message" | "task";
|
|
22
|
+
targetId: string;
|
|
23
|
+
targetName?: string;
|
|
24
|
+
targetType?: string;
|
|
25
|
+
senderId: string;
|
|
26
|
+
senderName: string;
|
|
27
|
+
messageId: string;
|
|
28
|
+
body: string;
|
|
29
|
+
threadRootId?: string;
|
|
30
|
+
noReply?: boolean;
|
|
31
|
+
mediaFields?: Record<string, string | undefined>;
|
|
32
|
+
ackSourceType?: "message" | "task_activity";
|
|
33
|
+
ackSourceId?: string;
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,MAAM,MAAM,UAAU,GAAG;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACjE,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,2DAA2D;AAC3D,MAAM,MAAM,aAAa,GAAG;IAC1B,eAAe,EAAE,OAAO,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,kBAAkB,EAAE,UAAU,EAAE,CAAC;IACjC,UAAU,EAAE,WAAW,EAAE,CAAC;CAC3B,CAAC;AAEF,4CAA4C;AAC5C,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACjD,aAAa,CAAC,EAAE,SAAS,GAAG,eAAe,CAAC;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@parall/agent-core",
|
|
3
|
+
"version": "1.13.1",
|
|
4
|
+
"description": "Shared agent runtime orchestration helpers for Parall",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/parall-hq/parall-mono",
|
|
9
|
+
"directory": "ts/agent-core"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"main": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"src"
|
|
23
|
+
],
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@parall/sdk": "1.13.1"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/node": "^22.0.0",
|
|
29
|
+
"typescript": "^5.7.0"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsc -b",
|
|
33
|
+
"test": "pnpm run build && node --test test/*.test.mjs"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { ParallClient } from "@parall/sdk";
|
|
2
|
+
import type { ParallEvent } from "./types.js";
|
|
3
|
+
|
|
4
|
+
export type GatewayLogger = {
|
|
5
|
+
info: (msg: string) => void;
|
|
6
|
+
warn: (msg: string) => void;
|
|
7
|
+
error: (msg: string) => void;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type DispatchContext = {
|
|
11
|
+
accountId: string;
|
|
12
|
+
apiUrl: string;
|
|
13
|
+
apiKey: string;
|
|
14
|
+
orgId: string;
|
|
15
|
+
agentUserId: string;
|
|
16
|
+
runtimeType: string;
|
|
17
|
+
runtimeKey: string;
|
|
18
|
+
sessionId?: string;
|
|
19
|
+
chatId?: string;
|
|
20
|
+
triggerMessageId?: string;
|
|
21
|
+
noReply: boolean;
|
|
22
|
+
stepIdFilePath?: string;
|
|
23
|
+
client: ParallClient;
|
|
24
|
+
log?: GatewayLogger;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type RuntimeEvent =
|
|
28
|
+
| { type: "thinking"; text: string; groupKey?: string }
|
|
29
|
+
| { type: "tool_call"; callId: string; toolName: string; input: unknown; startedAt?: string; groupKey?: string }
|
|
30
|
+
| { type: "tool_result"; callId: string; toolName: string; output: string; error?: string; durationMs?: number; groupKey?: string }
|
|
31
|
+
| { type: "text"; text: string; project?: boolean; groupKey?: string }
|
|
32
|
+
| { type: "error"; message: string };
|
|
33
|
+
|
|
34
|
+
export type DispatchOpts = {
|
|
35
|
+
event: ParallEvent;
|
|
36
|
+
earlierEvents?: ParallEvent[];
|
|
37
|
+
bodyForAgent: string;
|
|
38
|
+
sessionKey: string;
|
|
39
|
+
context: DispatchContext;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export type ForkSessionHandle = {
|
|
43
|
+
sessionKey: string;
|
|
44
|
+
[key: string]: unknown;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export type ForkOpts = {
|
|
48
|
+
sessionKey: string;
|
|
49
|
+
context: DispatchContext;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export type CleanupForkOpts = {
|
|
53
|
+
fork: ForkSessionHandle;
|
|
54
|
+
context: DispatchContext;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export interface DispatchAdapter {
|
|
58
|
+
/** Dispatch a Parall event to the runtime and emit normalized runtime events. */
|
|
59
|
+
dispatch(opts: DispatchOpts): AsyncIterable<RuntimeEvent>;
|
|
60
|
+
|
|
61
|
+
/** Fork the current runtime session for concurrent handling. Return null to buffer on main. */
|
|
62
|
+
forkSession?(opts: ForkOpts): Promise<ForkSessionHandle | null> | ForkSessionHandle | null;
|
|
63
|
+
|
|
64
|
+
/** Clean up a fork session created by forkSession(). */
|
|
65
|
+
cleanupFork?(opts: CleanupForkOpts): Promise<void> | void;
|
|
66
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ForkResult, ParallEvent } from "./types.js";
|
|
2
|
+
|
|
3
|
+
export function buildEventBody(event: ParallEvent): string {
|
|
4
|
+
const lines: string[] = [];
|
|
5
|
+
if (event.type === "message") {
|
|
6
|
+
lines.push(`[Event: message.new]`);
|
|
7
|
+
const chatLabel = event.targetName
|
|
8
|
+
? `"${event.targetName}" (${event.targetId})`
|
|
9
|
+
: event.targetId;
|
|
10
|
+
lines.push(`[Chat: ${chatLabel} | type: ${event.targetType ?? "unknown"}]`);
|
|
11
|
+
lines.push(`[From: ${event.senderName} (${event.senderId})]`);
|
|
12
|
+
lines.push(`[Message ID: ${event.messageId}]`);
|
|
13
|
+
if (event.threadRootId) lines.push(`[Thread: ${event.threadRootId}]`);
|
|
14
|
+
if (event.noReply) lines.push(`[Hint: no_reply]`);
|
|
15
|
+
if (event.mediaFields?.MediaUrl) {
|
|
16
|
+
lines.push(`[Attachment: ${event.mediaFields.MediaType ?? "file"} ${event.mediaFields.MediaUrl}]`);
|
|
17
|
+
}
|
|
18
|
+
lines.push("", event.body);
|
|
19
|
+
} else {
|
|
20
|
+
lines.push(`[Event: task.assigned]`);
|
|
21
|
+
const taskLabel = event.targetName
|
|
22
|
+
? `${event.targetName} (${event.targetId})`
|
|
23
|
+
: event.targetId;
|
|
24
|
+
lines.push(`[Task: ${taskLabel} | type: ${event.targetType ?? "task"}]`);
|
|
25
|
+
lines.push(`[Assigned by: ${event.senderName} (${event.senderId})]`);
|
|
26
|
+
lines.push("", event.body);
|
|
27
|
+
}
|
|
28
|
+
return lines.join("\n");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function buildForkResultPrefix(results: ForkResult[]): string {
|
|
32
|
+
if (!results.length) return "";
|
|
33
|
+
const blocks = results.map((result) => {
|
|
34
|
+
const lines = [`[Fork result]`];
|
|
35
|
+
lines.push(`[Handled: ${result.sourceEvent.type} — ${result.sourceEvent.summary}]`);
|
|
36
|
+
if (result.actions.length) lines.push(`[Actions: ${result.actions.join("; ")}]`);
|
|
37
|
+
return lines.join("\n");
|
|
38
|
+
});
|
|
39
|
+
return blocks.join("\n\n") + "\n\n---\n\n";
|
|
40
|
+
}
|