@parall/parel-channel 1.41.0 → 1.42.0
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/channel-prompt.d.ts +4 -3
- package/dist/channel-prompt.d.ts.map +1 -1
- package/dist/channel-prompt.js +4 -3
- package/dist/delivery.d.ts +23 -16
- package/dist/delivery.d.ts.map +1 -1
- package/dist/delivery.js +85 -116
- package/dist/fork.d.ts +8 -5
- package/dist/fork.d.ts.map +1 -1
- package/dist/fork.js +9 -6
- package/dist/inbound-channel.d.ts +1 -1
- package/dist/inbound-channel.d.ts.map +1 -1
- package/dist/inbound-channel.js +13 -7
- package/dist/inbound.d.ts.map +1 -1
- package/dist/inbound.js +87 -20
- package/dist/session.d.ts +67 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +166 -2
- package/dist/typed-dispatch.d.ts +14 -8
- package/dist/typed-dispatch.d.ts.map +1 -1
- package/dist/typed-dispatch.js +5 -3
- package/package.json +1 -1
- package/src/channel-prompt.ts +4 -3
- package/src/delivery.ts +84 -114
- package/src/fork.ts +9 -6
- package/src/inbound-channel.ts +14 -6
- package/src/inbound.ts +109 -23
- package/src/session.ts +201 -1
- package/src/typed-dispatch.ts +19 -11
package/dist/channel-prompt.d.ts
CHANGED
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
* chat shares the agent's ONE parel session, so consecutive turns can come
|
|
6
6
|
* from different conversations — each message is framed with its originating
|
|
7
7
|
* chat so the model registers the context switch instead of answering chat B
|
|
8
|
-
* with chat A's thread of thought. No reply hint: the
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* with chat A's thread of thought. No per-message reply hint: the system
|
|
9
|
+
* prompt teaches the CLI-only reply contract once (SSOT — plain text is
|
|
10
|
+
* never delivered; reply via `parall messages send`), and per-turn
|
|
11
|
+
* invocation context presets PRLL_CHAT_ID so the bare send hits this chat.
|
|
11
12
|
*
|
|
12
13
|
* External IM channel messages (buildChannelPrompt, channel_message
|
|
13
14
|
* dispatches). Mirrors agent-core's event-format.ts channel branch, adapted
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel-prompt.d.ts","sourceRoot":"","sources":["../src/channel-prompt.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"channel-prompt.d.ts","sourceRoot":"","sources":["../src/channel-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AASH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,WAAW,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAClC;AAmBD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAU5D;AAED,MAAM,WAAW,iBAAiB;IAChC,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAkBlE"}
|
package/dist/channel-prompt.js
CHANGED
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
* chat shares the agent's ONE parel session, so consecutive turns can come
|
|
6
6
|
* from different conversations — each message is framed with its originating
|
|
7
7
|
* chat so the model registers the context switch instead of answering chat B
|
|
8
|
-
* with chat A's thread of thought. No reply hint: the
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* with chat A's thread of thought. No per-message reply hint: the system
|
|
9
|
+
* prompt teaches the CLI-only reply contract once (SSOT — plain text is
|
|
10
|
+
* never delivered; reply via `parall messages send`), and per-turn
|
|
11
|
+
* invocation context presets PRLL_CHAT_ID so the bare send hits this chat.
|
|
11
12
|
*
|
|
12
13
|
* External IM channel messages (buildChannelPrompt, channel_message
|
|
13
14
|
* dispatches). Mirrors agent-core's event-format.ts channel branch, adapted
|
package/dist/delivery.d.ts
CHANGED
|
@@ -1,24 +1,31 @@
|
|
|
1
1
|
import type { ChannelDelivery, ConnectorContext, ConnectorEffect } from '@parel/plugin-sdk';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Turn-end delivery — which, under the platform reply contract, delivers
|
|
4
|
+
* NOTHING to the chat.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* The runtime-standard output contract (agent-dm-loop-prevention.md Layer 0,
|
|
7
|
+
* parel-reply-contract-alignment.md): plain turn output is never projected as
|
|
8
|
+
* a chat message — the agent replies explicitly via `parall messages send`
|
|
9
|
+
* from its sandbox, and that send carries the dispatch_source ledger binding.
|
|
10
|
+
* This hook records the turn-end text as a suppressed audit step on the
|
|
11
|
+
* session (the same posture the claude-agent / openclaw bridges enforce),
|
|
12
|
+
* runs a fence-checked ledger close, and a redundant session idle; nothing
|
|
13
|
+
* else.
|
|
9
14
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* by delivery id + message idempotency_key). The turn's PRIMARY done signal
|
|
14
|
-
* lives in onAgentEvent (turn_completed); the idle here is a deliberate
|
|
15
|
-
* redundant close for bindings without `observe: [turn]` — see the inline
|
|
16
|
-
* comment at the bottom.
|
|
15
|
+
* parel still auto-invokes deliver() at turn end for provider_http reply
|
|
16
|
+
* routes (C4) — ignoring the payload here is the connector's half of the
|
|
17
|
+
* contract; no parel-side change is needed.
|
|
17
18
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
19
|
+
* A fork-owned turn (replyRoute carries childRef) records its audit step on
|
|
20
|
+
* the CHILD's ase_ and idles IT — its session panel owns the turn, not
|
|
21
|
+
* main's. A stale childRef (fork purged by New Session / given up on) drops
|
|
22
|
+
* the text entirely: blind-recreating a fork ase_ under the new conversation
|
|
23
|
+
* line would resurrect pre-reset state.
|
|
24
|
+
*
|
|
25
|
+
* External IM turns (channel_message dispatches) route here too with a
|
|
26
|
+
* conversationId and no chatId: their reply goes out through the provider
|
|
27
|
+
* clip, agent-invoked, and their turn-end text was already deliberately
|
|
28
|
+
* undelivered — only the ledger close + redundant idle run for them.
|
|
22
29
|
*/
|
|
23
30
|
export declare function buildParallDelivery(delivery: ChannelDelivery, ctx: ConnectorContext): Promise<ConnectorEffect[]>;
|
|
24
31
|
//# sourceMappingURL=delivery.d.ts.map
|
package/dist/delivery.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delivery.d.ts","sourceRoot":"","sources":["../src/delivery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAa5F
|
|
1
|
+
{"version":3,"file":"delivery.d.ts","sourceRoot":"","sources":["../src/delivery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAa5F;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,eAAe,EACzB,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC,eAAe,EAAE,CAAC,CAgF5B"}
|
package/dist/delivery.js
CHANGED
|
@@ -1,134 +1,103 @@
|
|
|
1
|
-
import { parallApiUrl, parallOrgId, requireAgk } from './connect.js';
|
|
2
1
|
import { childRefKnown } from './fork.js';
|
|
3
|
-
import { ensureChildSession, ensureSession, invalidateChildSession, invalidateSession, patchSession,
|
|
2
|
+
import { completeFencedEnvelopes, createSuppressedTextStep, ensureChildSession, ensureSession, invalidateChildSession, invalidateSession, patchSession, TURN_ENVELOPE_KEY, } from './session.js';
|
|
4
3
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Turn-end delivery — which, under the platform reply contract, delivers
|
|
5
|
+
* NOTHING to the chat.
|
|
7
6
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* The runtime-standard output contract (agent-dm-loop-prevention.md Layer 0,
|
|
8
|
+
* parel-reply-contract-alignment.md): plain turn output is never projected as
|
|
9
|
+
* a chat message — the agent replies explicitly via `parall messages send`
|
|
10
|
+
* from its sandbox, and that send carries the dispatch_source ledger binding.
|
|
11
|
+
* This hook records the turn-end text as a suppressed audit step on the
|
|
12
|
+
* session (the same posture the claude-agent / openclaw bridges enforce),
|
|
13
|
+
* runs a fence-checked ledger close, and a redundant session idle; nothing
|
|
14
|
+
* else.
|
|
11
15
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* by delivery id + message idempotency_key). The turn's PRIMARY done signal
|
|
16
|
-
* lives in onAgentEvent (turn_completed); the idle here is a deliberate
|
|
17
|
-
* redundant close for bindings without `observe: [turn]` — see the inline
|
|
18
|
-
* comment at the bottom.
|
|
16
|
+
* parel still auto-invokes deliver() at turn end for provider_http reply
|
|
17
|
+
* routes (C4) — ignoring the payload here is the connector's half of the
|
|
18
|
+
* contract; no parel-side change is needed.
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* A fork-owned turn (replyRoute carries childRef) records its audit step on
|
|
21
|
+
* the CHILD's ase_ and idles IT — its session panel owns the turn, not
|
|
22
|
+
* main's. A stale childRef (fork purged by New Session / given up on) drops
|
|
23
|
+
* the text entirely: blind-recreating a fork ase_ under the new conversation
|
|
24
|
+
* line would resurrect pre-reset state.
|
|
25
|
+
*
|
|
26
|
+
* External IM turns (channel_message dispatches) route here too with a
|
|
27
|
+
* conversationId and no chatId: their reply goes out through the provider
|
|
28
|
+
* clip, agent-invoked, and their turn-end text was already deliberately
|
|
29
|
+
* undelivered — only the ledger close + redundant idle run for them.
|
|
24
30
|
*/
|
|
25
31
|
export async function buildParallDelivery(delivery, ctx) {
|
|
26
|
-
const apiUrl = parallApiUrl(ctx);
|
|
27
|
-
const agk = requireAgk(ctx);
|
|
28
|
-
const orgId = parallOrgId(ctx);
|
|
29
32
|
const route = (delivery.replyRoute?.data ?? {});
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// No delivery target: external IM turns (channel_message — the reply
|
|
33
|
-
// already went out through the provider clip, agent-invoked) and typed
|
|
34
|
-
// dispatch turns (task/schedule/trigger/wiki — the agent acts via its
|
|
35
|
-
// sandbox CLI). The turn-end text is deliberately NOT delivered anywhere
|
|
36
|
-
// (same contract as agent-core: plain output is not the reply). Only run
|
|
37
|
-
// the redundant idle so a binding without `observe: [turn]` still closes
|
|
38
|
-
// the session.
|
|
39
|
-
if (route.envelopeId) {
|
|
40
|
-
const sessionId = await ensureSession(ctx, { timeoutMs: 3_000 });
|
|
41
|
-
if (sessionId) {
|
|
42
|
-
await idleUnlessSuperseded(ctx, route.envelopeId, sessionId);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return [];
|
|
46
|
-
}
|
|
47
|
-
const payload = delivery.payload;
|
|
48
|
-
const text = typeof payload === 'string' ? payload : (payload?.text ?? '');
|
|
49
|
-
if (!text)
|
|
50
|
-
return [];
|
|
51
|
-
// Short timeout: this sits in front of the user-visible reply POST. Cache
|
|
52
|
-
// hit (every dispatch after the agent's first) is a store read; on a slow
|
|
53
|
-
// miss we degrade to a reply without the session link rather than delay it.
|
|
54
|
-
// A fork-owned envelope (replyRoute carries childRef) links to the CHILD's
|
|
55
|
-
// ase_ — its session panel owns this turn, not main's. Same short timeout
|
|
56
|
-
// as the main path: this sits in front of the user-visible reply POST, so
|
|
57
|
-
// a slow resolve degrades to a reply without the session link, never a
|
|
58
|
-
// 10s-delayed message.
|
|
33
|
+
// A fork-owned envelope whose bookkeeping is gone is a late/stale delivery
|
|
34
|
+
// (post-reset or post-give-up) — drop it entirely, audit step included.
|
|
59
35
|
const childLive = route.childRef ? await childRefKnown(ctx, route.childRef) : false;
|
|
60
36
|
if (route.childRef && !childLive) {
|
|
61
|
-
|
|
62
|
-
// given up on (black hole → the opening already re-planned onto main).
|
|
63
|
-
// Posting would land pre-reset output in the fresh conversation line, or
|
|
64
|
-
// duplicate a reply main already produced — drop it entirely (no POST,
|
|
65
|
-
// no retry effect).
|
|
66
|
-
console.warn('[parel-channel] dropping reply from stale fork', route.childRef);
|
|
37
|
+
console.warn('[parel-channel] dropping turn-end text from stale fork', route.childRef);
|
|
67
38
|
return [];
|
|
68
39
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
...(sessionId ? { agent_session_id: sessionId } : {}),
|
|
93
|
-
}),
|
|
94
|
-
};
|
|
95
|
-
try {
|
|
96
|
-
const res = await fetch(request.url, {
|
|
97
|
-
method: request.method,
|
|
98
|
-
headers: request.headers,
|
|
99
|
-
body: request.body,
|
|
100
|
-
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
101
|
-
});
|
|
102
|
-
if (!res.ok) {
|
|
103
|
-
// 4xx (bar 429) is permanent — retrying an unprocessable reply burns
|
|
104
|
-
// requests forever. Drop it (logged); turn_completed still closes the
|
|
105
|
-
// turn's indicator.
|
|
106
|
-
const permanent = res.status >= 400 && res.status < 500 && res.status !== 429;
|
|
107
|
-
if (!permanent)
|
|
108
|
-
throw new Error(`reply post failed (${res.status})`);
|
|
109
|
-
console.error(`[parel-channel] reply rejected (${res.status}) — dropping`);
|
|
40
|
+
if (route.chatId) {
|
|
41
|
+
const payload = delivery.payload;
|
|
42
|
+
const text = typeof payload === 'string' ? payload : (payload?.text ?? '');
|
|
43
|
+
if (text) {
|
|
44
|
+
// Audit-only: the session panel shows what the model produced, the
|
|
45
|
+
// chat never does. Short timeout — this hook sits at turn end, nothing
|
|
46
|
+
// user-visible waits on it. Fork turns land the step on the child ase_.
|
|
47
|
+
const sessionId = route.childRef
|
|
48
|
+
? await ensureChildSession(ctx, route.childRef, { timeoutMs: 3_000 })
|
|
49
|
+
: await ensureSession(ctx, { timeoutMs: 3_000 });
|
|
50
|
+
if (sessionId) {
|
|
51
|
+
const result = await createSuppressedTextStep(ctx, sessionId, {
|
|
52
|
+
subject: route.chatId,
|
|
53
|
+
deliveryId: delivery.id,
|
|
54
|
+
text,
|
|
55
|
+
});
|
|
56
|
+
if (result === 'stale') {
|
|
57
|
+
if (route.childRef)
|
|
58
|
+
await invalidateChildSession(ctx, route.childRef);
|
|
59
|
+
else
|
|
60
|
+
await invalidateSession(ctx);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
110
63
|
}
|
|
111
64
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
65
|
+
// Redundant turn-end ledger close, fence-checked — the deliver-side twin of
|
|
66
|
+
// onAgentEvent's complete. Exists for bindings WITHOUT `observe: [turn]`
|
|
67
|
+
// (the npm ^1 fallback path): there turn events never arrive and, with
|
|
68
|
+
// ack-on-emit gone, this hook is the only terminal ledger path — without it
|
|
69
|
+
// a delivered turn's row would stay live and re-emit on every TTL sweep.
|
|
70
|
+
// Under the normal artifact path both hooks run; the fence makes the
|
|
71
|
+
// overlap free (whichever completes first consumes it, the other skips).
|
|
72
|
+
// Fork-handled envelopes never wrote a fence, so this is a no-op for them
|
|
73
|
+
// (their ack machinery owns the ledger there).
|
|
74
|
+
// Known bound of this fallback: the replyRoute snapshot carries ONE
|
|
75
|
+
// envelope id, so a folded turn's OTHER sources heal only via the TTL
|
|
76
|
+
// re-emit here. Reaching that state needs a binding with injectInFlight
|
|
77
|
+
// ON and observe OFF — the platform template always sets both together,
|
|
78
|
+
// so it exists only on a hand-crafted binding.
|
|
79
|
+
if (route.envelopeId) {
|
|
80
|
+
await completeFencedEnvelopes(ctx, [route.envelopeId]);
|
|
115
81
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if (
|
|
128
|
-
await
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
82
|
+
const subject = route.chatId ?? route.conversationId;
|
|
83
|
+
if (subject) {
|
|
84
|
+
// Redundant done signal, kept deliberately: turn_completed (onAgentEvent)
|
|
85
|
+
// is the primary close for every turn — including no-reply turns — but a
|
|
86
|
+
// binding deployed without `observe: [turn]` would otherwise never idle.
|
|
87
|
+
// Child turns skip the marker guard entirely — the marker is main's; a
|
|
88
|
+
// child's own turn ending always idles the child ase_.
|
|
89
|
+
const sessionId = route.childRef
|
|
90
|
+
? await ensureChildSession(ctx, route.childRef, { timeoutMs: 3_000 })
|
|
91
|
+
: await ensureSession(ctx, { timeoutMs: 3_000 });
|
|
92
|
+
if (sessionId) {
|
|
93
|
+
if (route.childRef) {
|
|
94
|
+
const result = await patchSession(ctx, sessionId, { status: 'idle' });
|
|
95
|
+
if (result === 'stale')
|
|
96
|
+
await invalidateChildSession(ctx, route.childRef);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
await idleUnlessSuperseded(ctx, route.envelopeId, sessionId);
|
|
100
|
+
}
|
|
132
101
|
}
|
|
133
102
|
}
|
|
134
103
|
return [];
|
package/dist/fork.d.ts
CHANGED
|
@@ -135,11 +135,14 @@ export declare function handleChildSpawnFailed(ctx: ConnectorContext, event: Chi
|
|
|
135
135
|
* equivalent; the platform already excludes in-flight output from the seed,
|
|
136
136
|
* this line keeps the child from "finishing" main's visible work).
|
|
137
137
|
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
138
|
+
* Replies are CLI-only on EVERY fork turn (the platform reply contract —
|
|
139
|
+
* nothing auto-delivers, parel-reply-contract-alignment.md). The opening
|
|
140
|
+
* turn additionally has no envelope (it starts from the spawn input), so it
|
|
141
|
+
* gets no per-turn invocation context either — the prefix therefore spells
|
|
142
|
+
* out the full CLI reply command with the explicit chat target; follow-ups
|
|
143
|
+
* arrive as deliverTo envelopes whose invocation context presets
|
|
144
|
+
* PRLL_CHAT_ID, so the system prompt's bare `parall messages send` teaching
|
|
145
|
+
* covers them.
|
|
143
146
|
*/
|
|
144
147
|
export declare function buildForkScopePrefix(subject: string, threadRootId?: string): string;
|
|
145
148
|
//# sourceMappingURL=fork.d.ts.map
|
package/dist/fork.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fork.d.ts","sourceRoot":"","sources":["../src/fork.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"fork.d.ts","sourceRoot":"","sources":["../src/fork.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AA+CxF,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAS1C,eAAO,MAAM,iBAAiB,eAAe,CAAC;AAW9C,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,gFAAgF;IAChF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;2CAEuC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE;AAClB;oEACoE;GAClE;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAMxC;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC,CAwCvB;AAED;;sEAEsE;AACtE,wBAAsB,WAAW,CAC/B,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,OAAO,CAAC,CASlB;AAED;;;+EAG+E;AAC/E,wBAAsB,aAAa,CAAC,GAAG,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO7F;AAED,0EAA0E;AAC1E,wBAAsB,cAAc,CAClC,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAGlB;AAED,8EAA8E;AAC9E,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,gBAAgB,EACrB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED,iEAAiE;AACjE,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAE3C;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAoB7E;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,IAAI,CAAC,CAcf;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,UAAU,EAAE,CAAA;CAAE,GAAG,IAAI,CAAC,CA+BhE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,UAAU,EAAE,CAAA;CAAE,CAAC,CA2B3E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAYnF"}
|
package/dist/fork.js
CHANGED
|
@@ -301,11 +301,14 @@ export async function handleChildSpawnFailed(ctx, event) {
|
|
|
301
301
|
* equivalent; the platform already excludes in-flight output from the seed,
|
|
302
302
|
* this line keeps the child from "finishing" main's visible work).
|
|
303
303
|
*
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
*
|
|
308
|
-
*
|
|
304
|
+
* Replies are CLI-only on EVERY fork turn (the platform reply contract —
|
|
305
|
+
* nothing auto-delivers, parel-reply-contract-alignment.md). The opening
|
|
306
|
+
* turn additionally has no envelope (it starts from the spawn input), so it
|
|
307
|
+
* gets no per-turn invocation context either — the prefix therefore spells
|
|
308
|
+
* out the full CLI reply command with the explicit chat target; follow-ups
|
|
309
|
+
* arrive as deliverTo envelopes whose invocation context presets
|
|
310
|
+
* PRLL_CHAT_ID, so the system prompt's bare `parall messages send` teaching
|
|
311
|
+
* covers them.
|
|
309
312
|
*/
|
|
310
313
|
export function buildForkScopePrefix(subject, threadRootId) {
|
|
311
314
|
// Quoted-heredoc input form (mirrors agent-core's send hint): plain
|
|
@@ -316,5 +319,5 @@ export function buildForkScopePrefix(subject, threadRootId) {
|
|
|
316
319
|
: `parall messages send ${subject} --text-file - <<'EOF'`;
|
|
317
320
|
return (`[Fork scope: you are a parallel branch of your main session, handling ONE conversation (${subject}) only. ` +
|
|
318
321
|
`Act only on this conversation's request. Do not continue, complete, or produce output for other work visible in your inherited history — the main session owns it.]\n` +
|
|
319
|
-
`<system-reminder>Reply to THIS message with your sandbox CLI: \`${send}\` … \`EOF\` — the quoted heredoc keeps \`$\`, backticks and apostrophes literal.
|
|
322
|
+
`<system-reminder>Reply to THIS message with your sandbox CLI: \`${send}\` … \`EOF\` — the quoted heredoc keeps \`$\`, backticks and apostrophes literal. Your plain text output is NOT delivered anywhere — on this and every later message in this conversation, reply via \`parall messages send\`.</system-reminder>\n\n`);
|
|
320
323
|
}
|
|
@@ -25,5 +25,5 @@ export declare const PROVIDER_LOOKUP_TIMEOUT_MS = 3000;
|
|
|
25
25
|
* permanently unusable → ack-and-drop; a transient failure keeps the
|
|
26
26
|
* dispatch pending for the catch-up sweep.
|
|
27
27
|
*/
|
|
28
|
-
export declare function effectsForChannelDispatch(sourceId: string,
|
|
28
|
+
export declare function effectsForChannelDispatch(sourceId: string, ctx: ConnectorContext): Promise<ConnectorEffect[]>;
|
|
29
29
|
//# sourceMappingURL=inbound-channel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbound-channel.d.ts","sourceRoot":"","sources":["../src/inbound-channel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"inbound-channel.d.ts","sourceRoot":"","sources":["../src/inbound-channel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAiB3E;;;;GAIG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,OAAQ,CAAC;AAEhD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,yBAAyB,CAC7C,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC,eAAe,EAAE,CAAC,CA6J5B"}
|
package/dist/inbound-channel.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { buildChannelPrompt } from './channel-prompt.js';
|
|
2
2
|
import { parallApiUrl, parallOrgId, requireAgk } from './connect.js';
|
|
3
|
-
import { ackEffect, createChannelInputStep, ensureSession, invalidateSession, markDispatchReceived, patchSession, REQUEST_TIMEOUT_MS, TURN_ENVELOPE_KEY, } from './session.js';
|
|
3
|
+
import { ackEffect, createChannelInputStep, ensureSession, invalidateSession, markDispatchReceived, nextEnvelopeId, patchSession, readActiveEmit, REQUEST_TIMEOUT_MS, TURN_ENVELOPE_KEY, writeActiveEmit, } from './session.js';
|
|
4
4
|
/**
|
|
5
5
|
* External IM inbound (channel_message dispatches — Feishu/Slack via the
|
|
6
6
|
* platform-mediated channel, external-im-channel-design.md). Split from
|
|
@@ -27,7 +27,7 @@ export const PROVIDER_LOOKUP_TIMEOUT_MS = 3_000;
|
|
|
27
27
|
* permanently unusable → ack-and-drop; a transient failure keeps the
|
|
28
28
|
* dispatch pending for the catch-up sweep.
|
|
29
29
|
*/
|
|
30
|
-
export async function effectsForChannelDispatch(sourceId,
|
|
30
|
+
export async function effectsForChannelDispatch(sourceId, ctx) {
|
|
31
31
|
const apiUrl = parallApiUrl(ctx);
|
|
32
32
|
const orgId = parallOrgId(ctx);
|
|
33
33
|
const authHeaders = { Authorization: `Bearer ${requireAgk(ctx)}` };
|
|
@@ -75,10 +75,12 @@ export async function effectsForChannelDispatch(sourceId, dispatchId, ctx) {
|
|
|
75
75
|
: undefined;
|
|
76
76
|
const externalMessageId = msg?.external_message_id ? String(msg.external_message_id) : undefined;
|
|
77
77
|
// Progress reporting — identical ordering contract to the message path
|
|
78
|
-
// (see the comments there): received settles before
|
|
79
|
-
//
|
|
78
|
+
// (see the comments there): received settles before this function returns;
|
|
79
|
+
// the turnEnvelope marker goes down before any session write; the row
|
|
80
|
+
// stays 'received' until the turn event's complete-sources.
|
|
80
81
|
const receivedSettled = markDispatchReceived(ctx, 'channel_message', sourceId);
|
|
81
|
-
const
|
|
82
|
+
const priorEmit = await readActiveEmit(ctx, 'channel_message', sourceId);
|
|
83
|
+
const envelopeId = nextEnvelopeId('channel_message', sourceId, priorEmit);
|
|
82
84
|
let sessionId = await ensureSession(ctx);
|
|
83
85
|
if (sessionId) {
|
|
84
86
|
await ctx.store?.set(TURN_ENVELOPE_KEY, envelopeId).catch(() => { });
|
|
@@ -113,6 +115,7 @@ export async function effectsForChannelDispatch(sourceId, dispatchId, ctx) {
|
|
|
113
115
|
void recordConversationSession(ctx, conversationId, sessionId).catch(() => { });
|
|
114
116
|
}
|
|
115
117
|
await receivedSettled;
|
|
118
|
+
await writeActiveEmit(ctx, 'channel_message', sourceId, envelopeId);
|
|
116
119
|
return [
|
|
117
120
|
{
|
|
118
121
|
type: 'emitEvent',
|
|
@@ -154,10 +157,13 @@ export async function effectsForChannelDispatch(sourceId, dispatchId, ctx) {
|
|
|
154
157
|
},
|
|
155
158
|
// No invocation context: PRLL_CHAT_ID must not point CLI defaults at
|
|
156
159
|
// a chat that doesn't exist, and the reply targets (external ids)
|
|
157
|
-
// already ride the prompt verbatim.
|
|
160
|
+
// already ride the prompt verbatim. (So no PRLL_DISPATCH_SOURCE_*
|
|
161
|
+
// either — the external reply goes out through the provider clip,
|
|
162
|
+
// and this row's ledger close is the turn event's complete-sources.)
|
|
158
163
|
},
|
|
159
164
|
},
|
|
160
|
-
|
|
165
|
+
// No ack effect — see the message path (inbound.ts): the row stays
|
|
166
|
+
// received until complete-sources closes it.
|
|
161
167
|
];
|
|
162
168
|
}
|
|
163
169
|
/**
|
package/dist/inbound.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbound.d.ts","sourceRoot":"","sources":["../src/inbound.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACf,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"inbound.d.ts","sourceRoot":"","sources":["../src/inbound.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACf,MAAM,mBAAmB,CAAC;AAuH3B;kDACkD;AAClD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI,CASjE;AACD,wBAAgB,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAO9D;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,cAAc,EACrB,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC,eAAe,EAAE,CAAC,CAG5B;AAwCD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,EACtB,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC,eAAe,EAAE,CAAC,CAE5B;AA8BD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAE/E;AAwpBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAE7B"}
|