@parall/agent-core 1.36.1 → 1.38.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/bridge-workspace.d.ts +1 -1
- package/dist/bridge-workspace.d.ts.map +1 -1
- package/dist/bridge-workspace.js +13 -3
- package/dist/dispatch-adapter.d.ts +6 -0
- package/dist/dispatch-adapter.d.ts.map +1 -1
- package/dist/event-format.d.ts.map +1 -1
- package/dist/event-format.js +36 -1
- package/dist/gateway-base.d.ts +56 -0
- package/dist/gateway-base.d.ts.map +1 -1
- package/dist/gateway-base.js +459 -97
- package/dist/gateway-lane-flow.d.ts +74 -0
- package/dist/gateway-lane-flow.d.ts.map +1 -0
- package/dist/gateway-lane-flow.js +167 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/lane-key.d.ts +45 -0
- package/dist/lane-key.d.ts.map +1 -0
- package/dist/lane-key.js +34 -0
- package/dist/lane-ledger.d.ts +112 -0
- package/dist/lane-ledger.d.ts.map +1 -0
- package/dist/lane-ledger.js +333 -0
- package/dist/platform-config.d.ts +19 -0
- package/dist/platform-config.d.ts.map +1 -1
- package/dist/platform-config.js +72 -9
- package/dist/prompt-fragments.d.ts +1 -1
- package/dist/prompt-fragments.d.ts.map +1 -1
- package/dist/prompt-fragments.js +2 -0
- package/dist/skills/parall-platform.d.ts +1 -1
- package/dist/skills/parall-platform.d.ts.map +1 -1
- package/dist/skills/parall-platform.js +27 -6
- package/dist/types.d.ts +11 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/bridge-workspace.ts +13 -3
- package/src/dispatch-adapter.ts +6 -0
- package/src/event-format.ts +38 -1
- package/src/gateway-base.ts +637 -143
- package/src/gateway-lane-flow.ts +235 -0
- package/src/index.ts +2 -0
- package/src/lane-key.ts +67 -0
- package/src/lane-ledger.ts +370 -0
- package/src/platform-config.ts +85 -9
- package/src/prompt-fragments.ts +2 -0
- package/src/skills/parall-platform.ts +27 -6
- package/src/types.ts +17 -1
|
@@ -98,16 +98,35 @@ original discussion and its approval/rejection IS the precedent.
|
|
|
98
98
|
|
|
99
99
|
Each \`[Event: message.new]\` includes \`[Chat: ... (prll://cht_xxx)]\` — use that chat URI to reply.
|
|
100
100
|
|
|
101
|
+
> **How you pass the message body matters — your command runs through a shell.**
|
|
102
|
+
> Inside double quotes the shell expands \`$\`, backticks, and \`$(...)\` *before*
|
|
103
|
+
> the CLI sees them: \`--text "That costs $1,000"\` sends \`That costs ,000\`, and
|
|
104
|
+
> \`--text "$(cmd)"\` runs \`cmd\`. Single quotes instead break on apostrophes
|
|
105
|
+
> (\`I'm\`, \`don't\`). So do **not** wrap real message content in quotes — pass it
|
|
106
|
+
> through \`--text-file\` (a written file, or a quoted heredoc \`<<'EOF'\` that
|
|
107
|
+
> disables all expansion). Reserve \`--text "..."\` for short literals with no
|
|
108
|
+
> \`$\`, backtick, or apostrophe.
|
|
109
|
+
|
|
101
110
|
\`\`\`bash
|
|
102
|
-
#
|
|
103
|
-
|
|
111
|
+
# One-off reply → quoted heredoc into stdin. The quoted delimiter <<'EOF'
|
|
112
|
+
# disables ALL shell expansion, so $, backticks and apostrophes pass verbatim.
|
|
113
|
+
parall messages send prll://cht_xxx --text-file - <<'PARALL_EOF'
|
|
114
|
+
Sure — that's $1,000, and $(whoami) stays literal. I'm on it.
|
|
115
|
+
PARALL_EOF
|
|
116
|
+
|
|
117
|
+
# Longer / multi-line reply → write it with your file tool (no shell touches
|
|
118
|
+
# the body), then point --text-file at the file.
|
|
119
|
+
parall messages send prll://cht_xxx --text-file /tmp/reply.md
|
|
120
|
+
|
|
121
|
+
# Short literal with no $, backtick, or apostrophe → --text is fine.
|
|
122
|
+
parall messages send prll://cht_xxx --text "On it"
|
|
104
123
|
|
|
105
|
-
# Direct message by user URI or display name
|
|
106
|
-
parall dm prll://usr_xxx --text
|
|
124
|
+
# Direct message by user URI or display name (same --text-file / heredoc rules)
|
|
125
|
+
parall dm prll://usr_xxx --text-file /tmp/reply.md
|
|
107
126
|
parall dm "Alice" --text "Hello"
|
|
108
127
|
|
|
109
128
|
# Thread reply
|
|
110
|
-
parall messages send prll://cht_xxx --text
|
|
129
|
+
parall messages send prll://cht_xxx --text-file /tmp/reply.md --thread-root-id 01JWC...
|
|
111
130
|
|
|
112
131
|
# FYI message (no response expected — the recipient sees \`[Hint: no_reply]\`)
|
|
113
132
|
parall messages send prll://cht_xxx --text "FYI: done" --no-reply
|
|
@@ -139,7 +158,9 @@ parall messages send prll://cht_xxx --attachment att_xxx --text "See attached"
|
|
|
139
158
|
parall dm "Alice" --file /tmp/report.pdf --text "Report attached"
|
|
140
159
|
\`\`\`
|
|
141
160
|
|
|
142
|
-
\`--file\` and \`--attachment\` are mutually exclusive. \`--text\`
|
|
161
|
+
\`--file\` and \`--attachment\` are mutually exclusive. A caption (\`--text\` for
|
|
162
|
+
short literals, or \`--text-file\` for anything with \`$\`, backticks, or quotes)
|
|
163
|
+
can be combined with either.
|
|
143
164
|
|
|
144
165
|
## Approvals
|
|
145
166
|
|
package/dist/types.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export type DispatchState = {
|
|
|
26
26
|
};
|
|
27
27
|
/** Normalized inbound event from Parall. */
|
|
28
28
|
export type ParallEvent = {
|
|
29
|
-
type: 'message' | 'task' | 'task_comment' | 'wiki_comment' | 'schedule' | 'external_trigger' | 'approval';
|
|
29
|
+
type: 'message' | 'task' | 'task_comment' | 'wiki_comment' | 'schedule' | 'external_trigger' | 'channel_message' | 'approval';
|
|
30
30
|
targetId: string;
|
|
31
31
|
targetName?: string;
|
|
32
32
|
targetType?: string;
|
|
@@ -60,11 +60,20 @@ export type ParallEvent = {
|
|
|
60
60
|
externalConnectionDisplayName?: string;
|
|
61
61
|
externalIngressEventId?: string;
|
|
62
62
|
externalIngressEventType?: string;
|
|
63
|
+
/** External IM channel metadata, used for channel_message events. */
|
|
64
|
+
channelProvider?: string;
|
|
65
|
+
channelConversationType?: string;
|
|
66
|
+
/** Provider-side conversation id (the send_message target). */
|
|
67
|
+
channelExternalConversationId?: string;
|
|
68
|
+
/** Provider-side message id (in-thread reply target). */
|
|
69
|
+
channelExternalMessageId?: string;
|
|
63
70
|
/** Original event timestamp (e.g., message.created_at). When present,
|
|
64
71
|
* input steps use this instead of server insertion time for ordering. */
|
|
65
72
|
sentAt?: string;
|
|
66
|
-
ackSourceType?: 'message' | 'task_activity' | 'comment' | 'schedule_run' | 'external_trigger_run';
|
|
73
|
+
ackSourceType?: 'message' | 'task_activity' | 'comment' | 'schedule_run' | 'external_trigger_run' | 'channel_message';
|
|
67
74
|
ackSourceId?: string;
|
|
75
|
+
/** WorkItem id, when known (dispatch catch-up / re-drive hints carry it; live message.new does not). */
|
|
76
|
+
dispatchEventId?: string;
|
|
68
77
|
/** Unread message count in the target chat since agent's last interaction. */
|
|
69
78
|
unreadCount?: number;
|
|
70
79
|
/** Channel cursor: the last message ID the agent read. */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +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,mFAAmF;IACnF,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,sFAAsF;IACtF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,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;IAC1B,oFAAoF;IACpF,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC,CAAC;AAEF,4CAA4C;AAC5C,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EACA,SAAS,GACT,MAAM,GACN,cAAc,GACd,cAAc,GACd,UAAU,GACV,kBAAkB,GAClB,UAAU,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,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,KAAK,CAAC;QAClB,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;IACH,8DAA8D;IAC9D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,6BAA6B,CAAC,EAAE,MAAM,CAAC;IACvC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC;8EAC0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parall/agent-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.38.0",
|
|
4
4
|
"description": "Shared agent runtime orchestration helpers for Parall",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"@opentelemetry/sdk-logs": "^0.57.0",
|
|
36
36
|
"@opentelemetry/sdk-metrics": "^1.30.0",
|
|
37
37
|
"@opentelemetry/sdk-trace-node": "^1.30.0",
|
|
38
|
-
"@parall/sdk": "1.
|
|
38
|
+
"@parall/sdk": "1.38.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/node": "^22.0.0",
|
package/src/bridge-workspace.ts
CHANGED
|
@@ -24,11 +24,21 @@ To say something in a chat, you **must** invoke the Parall CLI via your shell/ex
|
|
|
24
24
|
|
|
25
25
|
All outbound interactions go through the \`parall\` CLI. Credentials are pre-injected as environment variables — no setup needed. If \`parall\` is not on PATH, use \`npx --yes @parall/cli@latest\` instead.
|
|
26
26
|
|
|
27
|
-
- \`parall messages send prll://cht_xxx --text
|
|
28
|
-
- \`parall dm prll://usr_xxx --text
|
|
27
|
+
- \`parall messages send prll://cht_xxx --text-file -\` — reply into the triggering chat (pipe the body via a quoted heredoc; see Shell-safety below)
|
|
28
|
+
- \`parall dm prll://usr_xxx --text-file - [--no-reply]\` — direct message another user
|
|
29
29
|
- \`parall tasks update prll://tsk_xxx --status in_progress\` — task state
|
|
30
30
|
- \`parall no-reply [--reason "..."]\` — explicitly declare this turn silent (audit signal; not required for silence, just clarifies intent)
|
|
31
31
|
|
|
32
|
+
**Shell-safety — never wrap real message content in double quotes.** Your command runs in a shell, which expands \`$\`, backticks, and \`$(...)\` inside \`"..."\` before the CLI sees them: \`--text "That costs $1,000"\` sends \`That costs ,000\`, and \`--text "$(cmd)"\` executes \`cmd\`. Pass message bodies via \`--text-file <path>\` (write the file first — no shell touches it) or a quoted heredoc that disables expansion:
|
|
33
|
+
|
|
34
|
+
\`\`\`bash
|
|
35
|
+
parall messages send prll://cht_xxx --text-file - <<'EOF'
|
|
36
|
+
That costs $1,000, and $(whoami) stays literal. I'm on it.
|
|
37
|
+
EOF
|
|
38
|
+
\`\`\`
|
|
39
|
+
|
|
40
|
+
Keep \`--text "..."\` for short literals with no \`$\`, backtick, or apostrophe.
|
|
41
|
+
|
|
32
42
|
The bridge injects Parall context via environment variables. The static credentials \`PRLL_API_URL\`, \`PRLL_API_KEY\`, and \`PRLL_ORG_ID\` are always set. \`PRLL_CONTEXT_FILE\` points to a per-session JSON file that the gateway updates each dispatch with \`session_id\`, \`chat_id\`, \`trigger_message_id\`, \`no_reply\`, and \`step_id\` (updated per tool call). The CLI reads this file automatically — you do not need to pass \`--chat\` or \`--session\` explicitly when the context file is present.
|
|
33
43
|
|
|
34
44
|
## Attachments
|
|
@@ -73,7 +83,7 @@ Messages may arrive with a \`[Thread: prll://msg_xxx]\` line in the event block,
|
|
|
73
83
|
|
|
74
84
|
### CLI usage
|
|
75
85
|
- The \`msg_xxx\` from the \`[Thread: prll://msg_xxx]\` line is the thread root ID — pass it as \`--thread-root-id\`
|
|
76
|
-
- Reply in a thread: \`parall messages send <chatId> --text
|
|
86
|
+
- Reply in a thread: \`parall messages send <chatId> --text-file /tmp/reply.md --thread-root-id <msgId>\`
|
|
77
87
|
- Read thread replies: \`parall messages list <chatId> --thread-root-id <msgId>\`
|
|
78
88
|
|
|
79
89
|
### Thread etiquette
|
package/src/dispatch-adapter.ts
CHANGED
|
@@ -23,6 +23,12 @@ export type DispatchContext = {
|
|
|
23
23
|
contextFilePath?: string;
|
|
24
24
|
/** @deprecated Use contextFilePath. Kept for runtimes that haven't migrated. */
|
|
25
25
|
stepIdFilePath?: string;
|
|
26
|
+
/**
|
|
27
|
+
* PRLL_CONTEXT_DIR contract: the per-agent directory holding per-lane
|
|
28
|
+
* dispatch context files (`<lane-key>.json`, see lane-key.ts). Stable for
|
|
29
|
+
* the life of the bridge — safe to pin into spawn env.
|
|
30
|
+
*/
|
|
31
|
+
contextDirPath?: string;
|
|
26
32
|
client: ParallClient;
|
|
27
33
|
log?: GatewayLogger;
|
|
28
34
|
};
|
package/src/event-format.ts
CHANGED
|
@@ -89,6 +89,24 @@ export function buildEventBody(event: ParallEvent): string {
|
|
|
89
89
|
if (event.scheduledFireAt) lines.push(`[Scheduled at: ${sanitizeMeta(event.scheduledFireAt)}]`);
|
|
90
90
|
if (event.attachedUri) lines.push(`[Attached: ${sanitizeMeta(event.attachedUri)}]`);
|
|
91
91
|
lines.push('', event.body);
|
|
92
|
+
} else if (event.type === 'channel_message') {
|
|
93
|
+
// External IM channel: the audience is OUTSIDE Parall. Frame the
|
|
94
|
+
// event so the agent writes for that audience — no prll:// refs, no
|
|
95
|
+
// internal cards/links in the reply body (they are dead links there).
|
|
96
|
+
lines.push(`[Event: channel.message]`);
|
|
97
|
+
const providerLabel = sanitizeMeta(event.channelProvider ?? 'external IM');
|
|
98
|
+
const convLabel = event.channelExternalConversationId
|
|
99
|
+
? `${sanitizeMeta(event.channelExternalConversationId)} (${sanitizeMeta(event.channelConversationType ?? 'conversation')})`
|
|
100
|
+
: sanitizeMeta(event.channelConversationType ?? 'conversation');
|
|
101
|
+
lines.push(`[Channel: ${providerLabel} | conversation: ${convLabel}]`);
|
|
102
|
+
lines.push(`[From: ${sanitizeMeta(event.senderName)} (external user, not a Parall member)]`);
|
|
103
|
+
if (event.channelExternalMessageId) {
|
|
104
|
+
lines.push(`[External message ID: ${sanitizeMeta(event.channelExternalMessageId)}]`);
|
|
105
|
+
}
|
|
106
|
+
lines.push(
|
|
107
|
+
`[Audience: this conversation lives on ${providerLabel}, OUTSIDE Parall. Readers cannot open prll:// links, Parall cards, or internal attachments — never include them in replies. Write plain conversational text.]`,
|
|
108
|
+
);
|
|
109
|
+
lines.push('', event.body);
|
|
92
110
|
} else if (event.type === 'external_trigger') {
|
|
93
111
|
lines.push(`[Event: external.trigger]`);
|
|
94
112
|
lines.push(`[Trigger: prll://${event.targetId}]`);
|
|
@@ -134,7 +152,7 @@ function buildSendMessageHint(event: ParallEvent): string {
|
|
|
134
152
|
}
|
|
135
153
|
|
|
136
154
|
if (event.targetId.startsWith('cht_')) {
|
|
137
|
-
return `\n<system-reminder>To reply, run
|
|
155
|
+
return `\n<system-reminder>To reply, run \`parall messages send prll://${event.targetId} --text-file - <<'EOF'\` … \`EOF\` — the quoted heredoc keeps \`$\`, backticks and apostrophes literal (plain \`--text "$1,000"\` sends \`,000\`). Your plain text output is not delivered to the chat.</system-reminder>`;
|
|
138
156
|
}
|
|
139
157
|
|
|
140
158
|
if (event.targetId.startsWith('tsk_')) {
|
|
@@ -145,6 +163,25 @@ function buildSendMessageHint(event: ParallEvent): string {
|
|
|
145
163
|
return `\n<system-reminder>To communicate, use the CLI: \`parall messages send\` / \`parall dm\`. Your plain text output is not delivered.</system-reminder>`;
|
|
146
164
|
}
|
|
147
165
|
|
|
166
|
+
if (event.type === 'channel_message') {
|
|
167
|
+
// Provider metadata is best-effort (the gateway's connection lookup can
|
|
168
|
+
// fail) — never instruct the agent to invoke a made-up clip alias.
|
|
169
|
+
const clipLabel = event.channelProvider
|
|
170
|
+
? `the \`${event.channelProvider}\` clip's`
|
|
171
|
+
: "your channel provider clip's";
|
|
172
|
+
const apiLabel = event.channelProvider ?? 'external platform';
|
|
173
|
+
const target = event.channelExternalConversationId
|
|
174
|
+
? `{"chat_id": "${event.channelExternalConversationId}", "text": "..."}`
|
|
175
|
+
: `{"chat_id": "<conversation id>", "text": "..."}`;
|
|
176
|
+
// Offer the in-thread alternative whenever the inbound message id is
|
|
177
|
+
// known — otherwise the hint nudges every threaded conversation toward a
|
|
178
|
+
// new top-level message.
|
|
179
|
+
const threadAlt = event.channelExternalMessageId
|
|
180
|
+
? ` To reply in-thread to this specific message, use {"message_id": "${event.channelExternalMessageId}", "text": "..."} instead.`
|
|
181
|
+
: '';
|
|
182
|
+
return `\n<system-reminder>To reply, invoke ${clipLabel} \`send_message\` command with ${target} — your plain text output is NOT delivered to the external conversation.${threadAlt} The same clip's \`call\` command reaches the wider ${apiLabel} API when needed.</system-reminder>`;
|
|
183
|
+
}
|
|
184
|
+
|
|
148
185
|
if (event.type === 'external_trigger' || event.targetId.startsWith('xtr_')) {
|
|
149
186
|
return `\n<system-reminder>This external trigger is incoming-only. Your plain text output is not sent back to the external provider. To communicate in Parall, use \`parall messages send\` / \`parall dm\`; provider-specific outbound actions require a separate capability.</system-reminder>`;
|
|
150
187
|
}
|