@poncho-ai/cli 0.38.0 → 0.38.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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +39 -0
- package/dist/{chunk-U643TWFX.js → chunk-W7SQVUB4.js} +72 -61
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.js +1 -1
- package/dist/{run-interactive-ink-CE7U47S5.js → run-interactive-ink-UKPUGCDW.js} +1 -1
- package/package.json +2 -2
- package/src/cron-helpers.ts +13 -4
- package/src/index.ts +76 -16
- package/src/web-ui-client.ts +6 -26
- package/src/web-ui-styles.ts +5 -14
- package/src/web-ui.ts +0 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @poncho-ai/cli@0.38.
|
|
2
|
+
> @poncho-ai/cli@0.38.1 build /home/runner/work/poncho-ai/poncho-ai/packages/cli
|
|
3
3
|
> tsup src/index.ts src/cli.ts --format esm --dts
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/cli.ts, src/index.ts
|
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
[34mCLI[39m tsup v8.5.1
|
|
8
8
|
[34mCLI[39m Target: es2022
|
|
9
9
|
[34mESM[39m Build start
|
|
10
|
-
[32mESM[39m [1mdist/index.js [22m[32m3.10 KB[39m
|
|
11
10
|
[32mESM[39m [1mdist/cli.js [22m[32m94.00 B[39m
|
|
12
|
-
[32mESM[39m [1mdist/
|
|
13
|
-
[32mESM[39m [1mdist/run-interactive-ink-
|
|
14
|
-
[32mESM[39m
|
|
11
|
+
[32mESM[39m [1mdist/index.js [22m[32m3.10 KB[39m
|
|
12
|
+
[32mESM[39m [1mdist/run-interactive-ink-UKPUGCDW.js [22m[32m23.38 KB[39m
|
|
13
|
+
[32mESM[39m [1mdist/chunk-W7SQVUB4.js [22m[32m601.92 KB[39m
|
|
14
|
+
[32mESM[39m ⚡️ Build success in 79ms
|
|
15
15
|
[34mDTS[39m Build start
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 4135ms
|
|
17
17
|
[32mDTS[39m [1mdist/cli.d.ts [22m[32m20.00 B[39m
|
|
18
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[
|
|
18
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m13.24 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
# @poncho-ai/cli
|
|
2
2
|
|
|
3
|
+
## 0.38.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`d6248c8`](https://github.com/cesr/poncho-ai/commit/d6248c8b6d22e0fd0becde9e31dff7c12c724d84) Thanks [@cesr](https://github.com/cesr)! - fix(cli, harness): unify turn-parameter assembly so `conversation_recall` works everywhere
|
|
8
|
+
|
|
9
|
+
The recall tool relies on three context parameters (`__conversationRecallCorpus`,
|
|
10
|
+
`__conversationListFn`, `__conversationFetchFn`) that were only injected for
|
|
11
|
+
user-initiated HTTP turns. Cron, reminder, messaging-adapter, chat-continuation,
|
|
12
|
+
subagent-callback, and tool-approval-resume runs all built their own
|
|
13
|
+
`runInput.parameters` object and silently omitted these — causing
|
|
14
|
+
`conversation_recall` to throw "not available in this environment" or return
|
|
15
|
+
empty results depending on the call mode.
|
|
16
|
+
|
|
17
|
+
Introduces a single `buildTurnParameters(conversation, opts)` helper in the CLI
|
|
18
|
+
that owns context-parameter assembly (recall functions, `__activeConversationId`,
|
|
19
|
+
`__ownerId`, messaging metadata, tool-result archive). HTTP, messaging, and
|
|
20
|
+
cron/reminder paths now go through it. The harness orchestrator's three
|
|
21
|
+
internal turn sites (chat continuation, subagent-callback resume, tool-approval
|
|
22
|
+
resume) now call the existing `hooks.buildRecallParams` so they pick up the
|
|
23
|
+
recall functions too.
|
|
24
|
+
|
|
25
|
+
- [#101](https://github.com/cesr/poncho-ai/pull/101) [`7cc2fb5`](https://github.com/cesr/poncho-ai/commit/7cc2fb592bf11b79916df5831598a991f1ac9c0c) Thanks [@cesr](https://github.com/cesr)! - fix(web-ui): thread panel displays anchor message + replies, not full snapshot
|
|
26
|
+
|
|
27
|
+
Shows the anchor message you forked on, plus any replies — and that's it.
|
|
28
|
+
The earlier snapshot is still part of the thread's context server-side
|
|
29
|
+
(the agent sees the full prior conversation), but the panel only
|
|
30
|
+
displays what's relevant: the message you replied to, and what came
|
|
31
|
+
after.
|
|
32
|
+
|
|
33
|
+
Also fixes the underlying scroll bug: `.thread-panel-messages` had
|
|
34
|
+
`flex: 1; overflow-y: auto` but no `min-height: 0`. In flex children
|
|
35
|
+
the default `min-height: auto` lets the item grow to fit content, so
|
|
36
|
+
the messages area never shrank below its content size and the scrollbar
|
|
37
|
+
never engaged.
|
|
38
|
+
|
|
39
|
+
- Updated dependencies [[`244a3a3`](https://github.com/cesr/poncho-ai/commit/244a3a310c6c52f9e8535b28fb25d77829583d3f), [`d6248c8`](https://github.com/cesr/poncho-ai/commit/d6248c8b6d22e0fd0becde9e31dff7c12c724d84)]:
|
|
40
|
+
- @poncho-ai/harness@0.39.1
|
|
41
|
+
|
|
3
42
|
## 0.38.0
|
|
4
43
|
|
|
5
44
|
### Minor Changes
|
|
@@ -2280,21 +2280,12 @@ var WEB_UI_STYLES = `
|
|
|
2280
2280
|
border-radius: 4px;
|
|
2281
2281
|
}
|
|
2282
2282
|
.thread-panel-close:hover { color: var(--fg); }
|
|
2283
|
-
.thread-panel-parent {
|
|
2284
|
-
padding: 12px 16px;
|
|
2285
|
-
border-bottom: 1px solid var(--border);
|
|
2286
|
-
background: var(--bg-bubble-user, rgba(0,0,0,0.02));
|
|
2287
|
-
font-size: 13px;
|
|
2288
|
-
}
|
|
2289
|
-
.thread-panel-parent .message-row {
|
|
2290
|
-
margin: 0;
|
|
2291
|
-
}
|
|
2292
|
-
.thread-panel-parent-empty {
|
|
2293
|
-
color: var(--fg-3);
|
|
2294
|
-
font-style: italic;
|
|
2295
|
-
}
|
|
2296
2283
|
.thread-panel-messages {
|
|
2297
|
-
flex: 1;
|
|
2284
|
+
flex: 1 1 0;
|
|
2285
|
+
/* min-height: 0 is required so this flex item can shrink below its
|
|
2286
|
+
content size \u2014 without it, overflow-y:auto never engages because
|
|
2287
|
+
the element grows to fit all messages instead of scrolling. */
|
|
2288
|
+
min-height: 0;
|
|
2298
2289
|
overflow-y: auto;
|
|
2299
2290
|
padding: 12px 16px;
|
|
2300
2291
|
}
|
|
@@ -2391,7 +2382,6 @@ var getWebUiClientScript = (markedSource2) => `
|
|
|
2391
2382
|
open: false,
|
|
2392
2383
|
threadId: null,
|
|
2393
2384
|
parentMessageId: null,
|
|
2394
|
-
parentMessage: null,
|
|
2395
2385
|
messages: [],
|
|
2396
2386
|
isStreaming: false,
|
|
2397
2387
|
abortController: null,
|
|
@@ -2438,7 +2428,6 @@ var getWebUiClientScript = (markedSource2) => `
|
|
|
2438
2428
|
threadPanel: $("thread-panel"),
|
|
2439
2429
|
threadPanelResize: $("thread-panel-resize"),
|
|
2440
2430
|
threadPanelClose: $("thread-panel-close"),
|
|
2441
|
-
threadPanelParent: $("thread-panel-parent"),
|
|
2442
2431
|
threadPanelMessages: $("thread-panel-messages"),
|
|
2443
2432
|
threadComposer: $("thread-composer"),
|
|
2444
2433
|
threadAttachBtn: $("thread-attach-btn"),
|
|
@@ -3769,24 +3758,6 @@ var getWebUiClientScript = (markedSource2) => `
|
|
|
3769
3758
|
root.scrollTop = root.scrollHeight;
|
|
3770
3759
|
};
|
|
3771
3760
|
|
|
3772
|
-
const renderThreadPanelParent = () => {
|
|
3773
|
-
const root = elements.threadPanelParent;
|
|
3774
|
-
if (!root) return;
|
|
3775
|
-
root.innerHTML = "";
|
|
3776
|
-
const parent = state.threadPanel.parentMessage;
|
|
3777
|
-
if (!parent) {
|
|
3778
|
-
const empty = document.createElement("div");
|
|
3779
|
-
empty.className = "thread-panel-parent-empty";
|
|
3780
|
-
empty.textContent = "No parent context";
|
|
3781
|
-
root.appendChild(empty);
|
|
3782
|
-
return;
|
|
3783
|
-
}
|
|
3784
|
-
const col = document.createElement("div");
|
|
3785
|
-
col.className = "messages-column";
|
|
3786
|
-
col.appendChild(buildSimpleMessageRow(parent));
|
|
3787
|
-
root.appendChild(col);
|
|
3788
|
-
};
|
|
3789
|
-
|
|
3790
3761
|
const closeThreadPanel = () => {
|
|
3791
3762
|
if (state.threadPanel.abortController) {
|
|
3792
3763
|
try { state.threadPanel.abortController.abort(); } catch (e) {}
|
|
@@ -3794,7 +3765,6 @@ var getWebUiClientScript = (markedSource2) => `
|
|
|
3794
3765
|
state.threadPanel.open = false;
|
|
3795
3766
|
state.threadPanel.threadId = null;
|
|
3796
3767
|
state.threadPanel.parentMessageId = null;
|
|
3797
|
-
state.threadPanel.parentMessage = null;
|
|
3798
3768
|
state.threadPanel.messages = [];
|
|
3799
3769
|
state.threadPanel.isStreaming = false;
|
|
3800
3770
|
state.threadPanel.abortController = null;
|
|
@@ -3823,14 +3793,15 @@ var getWebUiClientScript = (markedSource2) => `
|
|
|
3823
3793
|
const renderActiveTopForThreadPanel = (payload) => {
|
|
3824
3794
|
const conv = payload.conversation || {};
|
|
3825
3795
|
const allMsgs = Array.isArray(conv.messages) ? conv.messages : [];
|
|
3796
|
+
// Show the anchor message + replies. The earlier snapshot is still
|
|
3797
|
+
// part of the thread's context server-side, but the panel only
|
|
3798
|
+
// displays what's relevant: the message you forked on, plus what
|
|
3799
|
+
// came after.
|
|
3826
3800
|
const snapshotLength = (conv.threadMeta && typeof conv.threadMeta.snapshotLength === "number")
|
|
3827
3801
|
? conv.threadMeta.snapshotLength
|
|
3828
3802
|
: allMsgs.length;
|
|
3829
|
-
const
|
|
3830
|
-
|
|
3831
|
-
state.threadPanel.parentMessage = parent;
|
|
3832
|
-
state.threadPanel.messages = replies;
|
|
3833
|
-
renderThreadPanelParent();
|
|
3803
|
+
const startIdx = Math.max(0, snapshotLength - 1);
|
|
3804
|
+
state.threadPanel.messages = allMsgs.slice(startIdx);
|
|
3834
3805
|
renderThreadPanelMessages();
|
|
3835
3806
|
};
|
|
3836
3807
|
|
|
@@ -7842,7 +7813,6 @@ ${WEB_UI_STYLES}
|
|
|
7842
7813
|
<span class="thread-panel-title">Thread</span>
|
|
7843
7814
|
<button id="thread-panel-close" class="thread-panel-close" title="Close thread">×</button>
|
|
7844
7815
|
</div>
|
|
7845
|
-
<div id="thread-panel-parent" class="thread-panel-parent"></div>
|
|
7846
7816
|
<div id="thread-panel-messages" class="thread-panel-messages messages"></div>
|
|
7847
7817
|
<form id="thread-composer" class="composer thread-composer">
|
|
7848
7818
|
<div class="composer-inner">
|
|
@@ -10461,19 +10431,22 @@ var normalizeMessageForClient = (message) => {
|
|
|
10461
10431
|
}
|
|
10462
10432
|
return message;
|
|
10463
10433
|
};
|
|
10464
|
-
var runCronAgent = async (harnessRef, task, conversationId, historyMessages, toolResultArchive, onEvent) => {
|
|
10434
|
+
var runCronAgent = async (harnessRef, task, conversationId, historyMessages, toolResultArchive, onEvent, parameters, tenantId) => {
|
|
10465
10435
|
const turnTimestamp = Date.now();
|
|
10466
10436
|
const userMessageId = randomUUID2();
|
|
10467
10437
|
const assistantId = randomUUID2();
|
|
10438
|
+
const finalParameters = {
|
|
10439
|
+
...parameters ?? {},
|
|
10440
|
+
__activeConversationId: conversationId,
|
|
10441
|
+
[TOOL_RESULT_ARCHIVE_PARAM]: parameters?.[TOOL_RESULT_ARCHIVE_PARAM] ?? toolResultArchive ?? {}
|
|
10442
|
+
};
|
|
10468
10443
|
const execution = await executeConversationTurn({
|
|
10469
10444
|
harness: harnessRef,
|
|
10470
10445
|
runInput: {
|
|
10471
10446
|
task,
|
|
10472
10447
|
conversationId,
|
|
10473
|
-
|
|
10474
|
-
|
|
10475
|
-
[TOOL_RESULT_ARCHIVE_PARAM]: toolResultArchive ?? {}
|
|
10476
|
-
},
|
|
10448
|
+
tenantId: tenantId ?? void 0,
|
|
10449
|
+
parameters: finalParameters,
|
|
10477
10450
|
messages: historyMessages
|
|
10478
10451
|
},
|
|
10479
10452
|
onEvent
|
|
@@ -12718,7 +12691,7 @@ var runInteractive = async (workingDir, params) => {
|
|
|
12718
12691
|
await harness.initialize();
|
|
12719
12692
|
const identity = await ensureAgentIdentity2(workingDir);
|
|
12720
12693
|
try {
|
|
12721
|
-
const { runInteractiveInk } = await import("./run-interactive-ink-
|
|
12694
|
+
const { runInteractiveInk } = await import("./run-interactive-ink-UKPUGCDW.js");
|
|
12722
12695
|
await runInteractiveInk({
|
|
12723
12696
|
harness,
|
|
12724
12697
|
params,
|
|
@@ -13115,6 +13088,24 @@ data: ${JSON.stringify(statusPayload)}
|
|
|
13115
13088
|
__conversationFetchFn: conversationFetchFn
|
|
13116
13089
|
};
|
|
13117
13090
|
};
|
|
13091
|
+
const buildTurnParameters = (conversation, opts = {}) => {
|
|
13092
|
+
return withToolResultArchiveParam({
|
|
13093
|
+
...opts.bodyParameters ?? {},
|
|
13094
|
+
...buildRecallParams({
|
|
13095
|
+
ownerId: conversation.ownerId,
|
|
13096
|
+
tenantId: conversation.tenantId,
|
|
13097
|
+
excludeConversationId: conversation.conversationId
|
|
13098
|
+
}),
|
|
13099
|
+
...opts.messagingMetadata ? {
|
|
13100
|
+
__messaging_platform: opts.messagingMetadata.platform,
|
|
13101
|
+
__messaging_sender_id: opts.messagingMetadata.sender.id,
|
|
13102
|
+
__messaging_sender_name: opts.messagingMetadata.sender.name ?? "",
|
|
13103
|
+
__messaging_thread_id: opts.messagingMetadata.threadId
|
|
13104
|
+
} : {},
|
|
13105
|
+
__activeConversationId: conversation.conversationId,
|
|
13106
|
+
__ownerId: conversation.ownerId
|
|
13107
|
+
}, conversation);
|
|
13108
|
+
};
|
|
13118
13109
|
const messagingRoutes = /* @__PURE__ */ new Map();
|
|
13119
13110
|
const messagingRouteRegistrar = (method, path, routeHandler) => {
|
|
13120
13111
|
let byMethod = messagingRoutes.get(path);
|
|
@@ -13230,9 +13221,12 @@ data: ${JSON.stringify(statusPayload)}
|
|
|
13230
13221
|
const runInput = {
|
|
13231
13222
|
task: input2.task,
|
|
13232
13223
|
conversationId,
|
|
13224
|
+
tenantId: latestConversation?.tenantId ?? void 0,
|
|
13233
13225
|
messages: historyMessages,
|
|
13234
13226
|
files: input2.files,
|
|
13235
|
-
parameters:
|
|
13227
|
+
parameters: latestConversation ? buildTurnParameters(latestConversation, {
|
|
13228
|
+
messagingMetadata: input2.metadata
|
|
13229
|
+
}) : withToolResultArchiveParam({
|
|
13236
13230
|
...input2.metadata ? {
|
|
13237
13231
|
__messaging_platform: input2.metadata.platform,
|
|
13238
13232
|
__messaging_sender_id: input2.metadata.sender.id,
|
|
@@ -13240,7 +13234,7 @@ data: ${JSON.stringify(statusPayload)}
|
|
|
13240
13234
|
__messaging_thread_id: input2.metadata.threadId
|
|
13241
13235
|
} : {},
|
|
13242
13236
|
__activeConversationId: conversationId
|
|
13243
|
-
},
|
|
13237
|
+
}, { _toolResultArchive: {} })
|
|
13244
13238
|
};
|
|
13245
13239
|
try {
|
|
13246
13240
|
const execution = await executeConversationTurn2({
|
|
@@ -15270,12 +15264,7 @@ data: ${JSON.stringify(frame)}
|
|
|
15270
15264
|
task: messageText,
|
|
15271
15265
|
conversationId,
|
|
15272
15266
|
tenantId: ctx.tenantId ?? void 0,
|
|
15273
|
-
parameters:
|
|
15274
|
-
...bodyParameters ?? {},
|
|
15275
|
-
...buildRecallParams({ ownerId, tenantId: ctx.tenantId, excludeConversationId: conversationId }),
|
|
15276
|
-
__activeConversationId: conversationId,
|
|
15277
|
-
__ownerId: ownerId
|
|
15278
|
-
}, conversation),
|
|
15267
|
+
parameters: buildTurnParameters(conversation, { bodyParameters }),
|
|
15279
15268
|
messages: harnessMessages,
|
|
15280
15269
|
files: files.length > 0 ? files : void 0,
|
|
15281
15270
|
abortSignal: abortController.signal
|
|
@@ -15535,7 +15524,9 @@ ${cronJob.task}`;
|
|
|
15535
15524
|
conv._toolResultArchive,
|
|
15536
15525
|
async (event) => {
|
|
15537
15526
|
await telemetry.emit(event);
|
|
15538
|
-
}
|
|
15527
|
+
},
|
|
15528
|
+
buildTurnParameters(conv),
|
|
15529
|
+
conv.tenantId
|
|
15539
15530
|
);
|
|
15540
15531
|
const freshConv = await conversationStore.get(conv.conversationId);
|
|
15541
15532
|
if (freshConv) {
|
|
@@ -15603,7 +15594,9 @@ ${cronJob.task}`;
|
|
|
15603
15594
|
async (event) => {
|
|
15604
15595
|
broadcastEvent(convId, event);
|
|
15605
15596
|
await telemetry.emit(event);
|
|
15606
|
-
}
|
|
15597
|
+
},
|
|
15598
|
+
buildTurnParameters(conversation),
|
|
15599
|
+
conversation.tenantId
|
|
15607
15600
|
);
|
|
15608
15601
|
finishConversationStream(convId);
|
|
15609
15602
|
const freshConv = await conversationStore.get(convId);
|
|
@@ -15721,7 +15714,10 @@ Scheduled for: ${new Date(reminder.scheduledAt).toISOString()}` + recurrenceNote
|
|
|
15721
15714
|
framedMessage,
|
|
15722
15715
|
originConv.conversationId,
|
|
15723
15716
|
originConv.messages ?? [],
|
|
15724
|
-
originConv._toolResultArchive
|
|
15717
|
+
originConv._toolResultArchive,
|
|
15718
|
+
void 0,
|
|
15719
|
+
buildTurnParameters(originConv),
|
|
15720
|
+
originConv.tenantId
|
|
15725
15721
|
);
|
|
15726
15722
|
if (result.response) {
|
|
15727
15723
|
try {
|
|
@@ -15754,7 +15750,16 @@ Scheduled for: ${new Date(reminder.scheduledAt).toISOString()}` + recurrenceNote
|
|
|
15754
15750
|
`[reminder] ${reminder.task.slice(0, 80)} ${timestamp}`
|
|
15755
15751
|
);
|
|
15756
15752
|
const convId = conversation.conversationId;
|
|
15757
|
-
const result = await runCronAgent(
|
|
15753
|
+
const result = await runCronAgent(
|
|
15754
|
+
harness,
|
|
15755
|
+
framedMessage,
|
|
15756
|
+
convId,
|
|
15757
|
+
[],
|
|
15758
|
+
void 0,
|
|
15759
|
+
void 0,
|
|
15760
|
+
buildTurnParameters(conversation),
|
|
15761
|
+
conversation.tenantId
|
|
15762
|
+
);
|
|
15758
15763
|
const freshConv = await conversationStore.get(convId);
|
|
15759
15764
|
if (freshConv) {
|
|
15760
15765
|
freshConv.messages = buildCronMessages(framedMessage, [], result);
|
|
@@ -15787,6 +15792,7 @@ Scheduled for: ${new Date(reminder.scheduledAt).toISOString()}` + recurrenceNote
|
|
|
15787
15792
|
handler._finishConversationStream = finishConversationStream;
|
|
15788
15793
|
handler._checkAndFireReminders = checkAndFireReminders;
|
|
15789
15794
|
handler._reminderPollIntervalMs = reminderPollWindowMs;
|
|
15795
|
+
handler._buildTurnParameters = buildTurnParameters;
|
|
15790
15796
|
orchestrator.recoverStaleSubagents().catch(
|
|
15791
15797
|
(err) => subagentLog.warn(`failed to recover stale subagent runs: ${formatError(err)}`)
|
|
15792
15798
|
);
|
|
@@ -15817,6 +15823,7 @@ var startDevServer = async (port, options) => {
|
|
|
15817
15823
|
const activeRuns = handler._activeConversationRuns;
|
|
15818
15824
|
const deferredCallbacks = handler._pendingCallbackNeeded;
|
|
15819
15825
|
const runCallback = handler._processSubagentCallback;
|
|
15826
|
+
const buildParams = handler._buildTurnParameters;
|
|
15820
15827
|
if (!harnessRef || !store) return;
|
|
15821
15828
|
for (const [jobName, config] of entries) {
|
|
15822
15829
|
const job = new Cron(
|
|
@@ -15873,7 +15880,9 @@ ${config.task}`;
|
|
|
15873
15880
|
convId,
|
|
15874
15881
|
historyMessages,
|
|
15875
15882
|
conversation._toolResultArchive,
|
|
15876
|
-
broadcastCh ? (ev) => broadcastCh(convId, ev) : void 0
|
|
15883
|
+
broadcastCh ? (ev) => broadcastCh(convId, ev) : void 0,
|
|
15884
|
+
buildParams?.(conversation),
|
|
15885
|
+
conversation.tenantId
|
|
15877
15886
|
);
|
|
15878
15887
|
handler._finishConversationStream?.(convId);
|
|
15879
15888
|
const freshConv = await store.get(convId);
|
|
@@ -15941,7 +15950,9 @@ ${config.task}`;
|
|
|
15941
15950
|
cronConvId,
|
|
15942
15951
|
[],
|
|
15943
15952
|
conversation._toolResultArchive,
|
|
15944
|
-
broadcast ? (ev) => broadcast(cronConvId, ev) : void 0
|
|
15953
|
+
broadcast ? (ev) => broadcast(cronConvId, ev) : void 0,
|
|
15954
|
+
buildParams?.(conversation),
|
|
15955
|
+
conversation.tenantId
|
|
15945
15956
|
);
|
|
15946
15957
|
handler._finishConversationStream?.(cronConvId);
|
|
15947
15958
|
const freshConv = await store.get(cronConvId);
|
package/dist/cli.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -46,7 +46,7 @@ type CronRunResult = {
|
|
|
46
46
|
/** Timestamp shared by user and assistant messages of this turn. */
|
|
47
47
|
turnTimestamp: number;
|
|
48
48
|
};
|
|
49
|
-
declare const runCronAgent: (harnessRef: AgentHarness, task: string, conversationId: string, historyMessages: Message[], toolResultArchive?: Conversation["_toolResultArchive"], onEvent?: (event: AgentEvent) => void | Promise<void
|
|
49
|
+
declare const runCronAgent: (harnessRef: AgentHarness, task: string, conversationId: string, historyMessages: Message[], toolResultArchive?: Conversation["_toolResultArchive"], onEvent?: (event: AgentEvent) => void | Promise<void>, parameters?: Record<string, unknown>, tenantId?: string | null) => Promise<CronRunResult>;
|
|
50
50
|
declare const buildCronMessages: (task: string, historyMessages: Message[], result: CronRunResult) => Message[];
|
|
51
51
|
/** Append a cron turn to a freshly-fetched conversation (avoids overwriting concurrent writes). */
|
|
52
52
|
declare const appendCronTurn: (conv: Conversation, task: string, result: CronRunResult) => void;
|
|
@@ -224,6 +224,17 @@ type RequestHandler = ((request: IncomingMessage, response: ServerResponse) => P
|
|
|
224
224
|
duration: number;
|
|
225
225
|
}>;
|
|
226
226
|
_reminderPollIntervalMs?: number;
|
|
227
|
+
_buildTurnParameters?: (conversation: Conversation, opts?: {
|
|
228
|
+
bodyParameters?: Record<string, unknown>;
|
|
229
|
+
messagingMetadata?: {
|
|
230
|
+
platform: string;
|
|
231
|
+
sender: {
|
|
232
|
+
id: string;
|
|
233
|
+
name?: string | null;
|
|
234
|
+
};
|
|
235
|
+
threadId?: string;
|
|
236
|
+
};
|
|
237
|
+
}) => Record<string, unknown>;
|
|
227
238
|
};
|
|
228
239
|
declare const createRequestHandler: (options?: {
|
|
229
240
|
workingDir?: string;
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@poncho-ai/cli",
|
|
3
|
-
"version": "0.38.
|
|
3
|
+
"version": "0.38.1",
|
|
4
4
|
"description": "CLI for building and deploying AI agents",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"react": "^19.2.4",
|
|
29
29
|
"react-devtools-core": "^6.1.5",
|
|
30
30
|
"yaml": "^2.8.1",
|
|
31
|
-
"@poncho-ai/harness": "0.39.
|
|
31
|
+
"@poncho-ai/harness": "0.39.1",
|
|
32
32
|
"@poncho-ai/messaging": "0.8.4",
|
|
33
33
|
"@poncho-ai/sdk": "1.9.0"
|
|
34
34
|
},
|
package/src/cron-helpers.ts
CHANGED
|
@@ -76,19 +76,28 @@ export const runCronAgent = async (
|
|
|
76
76
|
historyMessages: Message[],
|
|
77
77
|
toolResultArchive?: Conversation["_toolResultArchive"],
|
|
78
78
|
onEvent?: (event: AgentEvent) => void | Promise<void>,
|
|
79
|
+
parameters?: Record<string, unknown>,
|
|
80
|
+
tenantId?: string | null,
|
|
79
81
|
): Promise<CronRunResult> => {
|
|
80
82
|
const turnTimestamp = Date.now();
|
|
81
83
|
const userMessageId = randomUUID();
|
|
82
84
|
const assistantId = randomUUID();
|
|
85
|
+
// Callers normally build `parameters` via buildTurnParameters() which
|
|
86
|
+
// already merges the tool-result archive. The `toolResultArchive` arg is a
|
|
87
|
+
// fallback for callers that don't (legacy / minimal callers).
|
|
88
|
+
const finalParameters = {
|
|
89
|
+
...(parameters ?? {}),
|
|
90
|
+
__activeConversationId: conversationId,
|
|
91
|
+
[TOOL_RESULT_ARCHIVE_PARAM]:
|
|
92
|
+
parameters?.[TOOL_RESULT_ARCHIVE_PARAM] ?? toolResultArchive ?? {},
|
|
93
|
+
};
|
|
83
94
|
const execution = await executeConversationTurn({
|
|
84
95
|
harness: harnessRef,
|
|
85
96
|
runInput: {
|
|
86
97
|
task,
|
|
87
98
|
conversationId,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
[TOOL_RESULT_ARCHIVE_PARAM]: toolResultArchive ?? {},
|
|
91
|
-
},
|
|
99
|
+
tenantId: tenantId ?? undefined,
|
|
100
|
+
parameters: finalParameters,
|
|
92
101
|
messages: historyMessages,
|
|
93
102
|
},
|
|
94
103
|
onEvent,
|
package/src/index.ts
CHANGED
|
@@ -307,6 +307,13 @@ export type RequestHandler = ((
|
|
|
307
307
|
_finishConversationStream?: (conversationId: string) => void;
|
|
308
308
|
_checkAndFireReminders?: () => Promise<{ fired: string[]; count: number; duration: number }>;
|
|
309
309
|
_reminderPollIntervalMs?: number;
|
|
310
|
+
_buildTurnParameters?: (
|
|
311
|
+
conversation: Conversation,
|
|
312
|
+
opts?: {
|
|
313
|
+
bodyParameters?: Record<string, unknown>;
|
|
314
|
+
messagingMetadata?: { platform: string; sender: { id: string; name?: string | null }; threadId?: string };
|
|
315
|
+
},
|
|
316
|
+
) => Record<string, unknown>;
|
|
310
317
|
};
|
|
311
318
|
|
|
312
319
|
export const createRequestHandler = async (options?: {
|
|
@@ -681,6 +688,40 @@ export const createRequestHandler = async (options?: {
|
|
|
681
688
|
};
|
|
682
689
|
};
|
|
683
690
|
|
|
691
|
+
// ---------------------------------------------------------------------------
|
|
692
|
+
// Single helper for assembling runInput.parameters across every turn entry
|
|
693
|
+
// point (HTTP route, messaging adapter, cron, reminder). All `__`-prefixed
|
|
694
|
+
// context params live here so adding a new one only requires one edit.
|
|
695
|
+
// ---------------------------------------------------------------------------
|
|
696
|
+
const buildTurnParameters = (
|
|
697
|
+
conversation: Conversation,
|
|
698
|
+
opts: {
|
|
699
|
+
bodyParameters?: Record<string, unknown>;
|
|
700
|
+
messagingMetadata?: {
|
|
701
|
+
platform: string;
|
|
702
|
+
sender: { id: string; name?: string | null };
|
|
703
|
+
threadId?: string;
|
|
704
|
+
};
|
|
705
|
+
} = {},
|
|
706
|
+
): Record<string, unknown> => {
|
|
707
|
+
return withToolResultArchiveParam({
|
|
708
|
+
...(opts.bodyParameters ?? {}),
|
|
709
|
+
...buildRecallParams({
|
|
710
|
+
ownerId: conversation.ownerId,
|
|
711
|
+
tenantId: conversation.tenantId,
|
|
712
|
+
excludeConversationId: conversation.conversationId,
|
|
713
|
+
}),
|
|
714
|
+
...(opts.messagingMetadata ? {
|
|
715
|
+
__messaging_platform: opts.messagingMetadata.platform,
|
|
716
|
+
__messaging_sender_id: opts.messagingMetadata.sender.id,
|
|
717
|
+
__messaging_sender_name: opts.messagingMetadata.sender.name ?? "",
|
|
718
|
+
__messaging_thread_id: opts.messagingMetadata.threadId,
|
|
719
|
+
} : {}),
|
|
720
|
+
__activeConversationId: conversation.conversationId,
|
|
721
|
+
__ownerId: conversation.ownerId,
|
|
722
|
+
}, conversation);
|
|
723
|
+
};
|
|
724
|
+
|
|
684
725
|
// Subagent lifecycle extracted to AgentOrchestrator (Phase 5).
|
|
685
726
|
|
|
686
727
|
// ---------------------------------------------------------------------------
|
|
@@ -828,17 +869,22 @@ export const createRequestHandler = async (options?: {
|
|
|
828
869
|
const runInput = {
|
|
829
870
|
task: input.task,
|
|
830
871
|
conversationId,
|
|
872
|
+
tenantId: latestConversation?.tenantId ?? undefined,
|
|
831
873
|
messages: historyMessages,
|
|
832
874
|
files: input.files,
|
|
833
|
-
parameters:
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
875
|
+
parameters: latestConversation
|
|
876
|
+
? buildTurnParameters(latestConversation, {
|
|
877
|
+
messagingMetadata: input.metadata,
|
|
878
|
+
})
|
|
879
|
+
: withToolResultArchiveParam({
|
|
880
|
+
...(input.metadata ? {
|
|
881
|
+
__messaging_platform: input.metadata.platform,
|
|
882
|
+
__messaging_sender_id: input.metadata.sender.id,
|
|
883
|
+
__messaging_sender_name: input.metadata.sender.name ?? "",
|
|
884
|
+
__messaging_thread_id: input.metadata.threadId,
|
|
885
|
+
} : {}),
|
|
886
|
+
__activeConversationId: conversationId,
|
|
887
|
+
}, { _toolResultArchive: {} } as Conversation),
|
|
842
888
|
};
|
|
843
889
|
|
|
844
890
|
try {
|
|
@@ -3170,12 +3216,7 @@ export const createRequestHandler = async (options?: {
|
|
|
3170
3216
|
task: messageText,
|
|
3171
3217
|
conversationId,
|
|
3172
3218
|
tenantId: ctx.tenantId ?? undefined,
|
|
3173
|
-
parameters:
|
|
3174
|
-
...(bodyParameters ?? {}),
|
|
3175
|
-
...buildRecallParams({ ownerId, tenantId: ctx.tenantId, excludeConversationId: conversationId }),
|
|
3176
|
-
__activeConversationId: conversationId,
|
|
3177
|
-
__ownerId: ownerId,
|
|
3178
|
-
}, conversation),
|
|
3219
|
+
parameters: buildTurnParameters(conversation, { bodyParameters }),
|
|
3179
3220
|
messages: harnessMessages,
|
|
3180
3221
|
files: files.length > 0 ? files : undefined,
|
|
3181
3222
|
abortSignal: abortController.signal,
|
|
@@ -3456,6 +3497,8 @@ export const createRequestHandler = async (options?: {
|
|
|
3456
3497
|
const result = await runCronAgent(harness, task, conv.conversationId, historyMessages,
|
|
3457
3498
|
conv._toolResultArchive,
|
|
3458
3499
|
async (event) => { await telemetry.emit(event); },
|
|
3500
|
+
buildTurnParameters(conv),
|
|
3501
|
+
conv.tenantId,
|
|
3459
3502
|
);
|
|
3460
3503
|
|
|
3461
3504
|
const freshConv = await conversationStore.get(conv.conversationId);
|
|
@@ -3526,6 +3569,8 @@ export const createRequestHandler = async (options?: {
|
|
|
3526
3569
|
broadcastEvent(convId, event);
|
|
3527
3570
|
await telemetry.emit(event);
|
|
3528
3571
|
},
|
|
3572
|
+
buildTurnParameters(conversation),
|
|
3573
|
+
conversation.tenantId,
|
|
3529
3574
|
);
|
|
3530
3575
|
finishConversationStream(convId);
|
|
3531
3576
|
|
|
@@ -3673,6 +3718,9 @@ export const createRequestHandler = async (options?: {
|
|
|
3673
3718
|
harness, framedMessage, originConv.conversationId,
|
|
3674
3719
|
originConv.messages ?? [],
|
|
3675
3720
|
originConv._toolResultArchive,
|
|
3721
|
+
undefined,
|
|
3722
|
+
buildTurnParameters(originConv),
|
|
3723
|
+
originConv.tenantId,
|
|
3676
3724
|
);
|
|
3677
3725
|
if (result.response) {
|
|
3678
3726
|
try {
|
|
@@ -3705,7 +3753,13 @@ export const createRequestHandler = async (options?: {
|
|
|
3705
3753
|
`[reminder] ${reminder.task.slice(0, 80)} ${timestamp}`,
|
|
3706
3754
|
);
|
|
3707
3755
|
const convId = conversation.conversationId;
|
|
3708
|
-
const result = await runCronAgent(
|
|
3756
|
+
const result = await runCronAgent(
|
|
3757
|
+
harness, framedMessage, convId, [],
|
|
3758
|
+
undefined,
|
|
3759
|
+
undefined,
|
|
3760
|
+
buildTurnParameters(conversation),
|
|
3761
|
+
conversation.tenantId,
|
|
3762
|
+
);
|
|
3709
3763
|
const freshConv = await conversationStore.get(convId);
|
|
3710
3764
|
if (freshConv) {
|
|
3711
3765
|
freshConv.messages = buildCronMessages(framedMessage, [], result);
|
|
@@ -3741,6 +3795,7 @@ export const createRequestHandler = async (options?: {
|
|
|
3741
3795
|
handler._finishConversationStream = finishConversationStream;
|
|
3742
3796
|
handler._checkAndFireReminders = checkAndFireReminders;
|
|
3743
3797
|
handler._reminderPollIntervalMs = reminderPollWindowMs;
|
|
3798
|
+
handler._buildTurnParameters = buildTurnParameters;
|
|
3744
3799
|
|
|
3745
3800
|
// Recover stale subagent runs that were "running" when the server last stopped
|
|
3746
3801
|
orchestrator.recoverStaleSubagents().catch(err =>
|
|
@@ -3785,6 +3840,7 @@ export const startDevServer = async (
|
|
|
3785
3840
|
const activeRuns = handler._activeConversationRuns;
|
|
3786
3841
|
const deferredCallbacks = handler._pendingCallbackNeeded;
|
|
3787
3842
|
const runCallback = handler._processSubagentCallback;
|
|
3843
|
+
const buildParams = handler._buildTurnParameters;
|
|
3788
3844
|
if (!harnessRef || !store) return;
|
|
3789
3845
|
|
|
3790
3846
|
for (const [jobName, config] of entries) {
|
|
@@ -3845,6 +3901,8 @@ export const startDevServer = async (
|
|
|
3845
3901
|
const result = await runCronAgent(harnessRef, task, convId, historyMessages,
|
|
3846
3902
|
conversation._toolResultArchive,
|
|
3847
3903
|
broadcastCh ? (ev) => broadcastCh(convId, ev) : undefined,
|
|
3904
|
+
buildParams?.(conversation),
|
|
3905
|
+
conversation.tenantId,
|
|
3848
3906
|
);
|
|
3849
3907
|
handler._finishConversationStream?.(convId);
|
|
3850
3908
|
|
|
@@ -3913,6 +3971,8 @@ export const startDevServer = async (
|
|
|
3913
3971
|
const result = await runCronAgent(harnessRef, config.task, cronConvId, [],
|
|
3914
3972
|
conversation._toolResultArchive,
|
|
3915
3973
|
broadcast ? (ev) => broadcast(cronConvId!, ev) : undefined,
|
|
3974
|
+
buildParams?.(conversation),
|
|
3975
|
+
conversation.tenantId,
|
|
3916
3976
|
);
|
|
3917
3977
|
handler._finishConversationStream?.(cronConvId);
|
|
3918
3978
|
const freshConv = await store.get(cronConvId);
|
package/src/web-ui-client.ts
CHANGED
|
@@ -59,7 +59,6 @@ export const getWebUiClientScript = (markedSource: string): string => `
|
|
|
59
59
|
open: false,
|
|
60
60
|
threadId: null,
|
|
61
61
|
parentMessageId: null,
|
|
62
|
-
parentMessage: null,
|
|
63
62
|
messages: [],
|
|
64
63
|
isStreaming: false,
|
|
65
64
|
abortController: null,
|
|
@@ -106,7 +105,6 @@ export const getWebUiClientScript = (markedSource: string): string => `
|
|
|
106
105
|
threadPanel: $("thread-panel"),
|
|
107
106
|
threadPanelResize: $("thread-panel-resize"),
|
|
108
107
|
threadPanelClose: $("thread-panel-close"),
|
|
109
|
-
threadPanelParent: $("thread-panel-parent"),
|
|
110
108
|
threadPanelMessages: $("thread-panel-messages"),
|
|
111
109
|
threadComposer: $("thread-composer"),
|
|
112
110
|
threadAttachBtn: $("thread-attach-btn"),
|
|
@@ -1437,24 +1435,6 @@ export const getWebUiClientScript = (markedSource: string): string => `
|
|
|
1437
1435
|
root.scrollTop = root.scrollHeight;
|
|
1438
1436
|
};
|
|
1439
1437
|
|
|
1440
|
-
const renderThreadPanelParent = () => {
|
|
1441
|
-
const root = elements.threadPanelParent;
|
|
1442
|
-
if (!root) return;
|
|
1443
|
-
root.innerHTML = "";
|
|
1444
|
-
const parent = state.threadPanel.parentMessage;
|
|
1445
|
-
if (!parent) {
|
|
1446
|
-
const empty = document.createElement("div");
|
|
1447
|
-
empty.className = "thread-panel-parent-empty";
|
|
1448
|
-
empty.textContent = "No parent context";
|
|
1449
|
-
root.appendChild(empty);
|
|
1450
|
-
return;
|
|
1451
|
-
}
|
|
1452
|
-
const col = document.createElement("div");
|
|
1453
|
-
col.className = "messages-column";
|
|
1454
|
-
col.appendChild(buildSimpleMessageRow(parent));
|
|
1455
|
-
root.appendChild(col);
|
|
1456
|
-
};
|
|
1457
|
-
|
|
1458
1438
|
const closeThreadPanel = () => {
|
|
1459
1439
|
if (state.threadPanel.abortController) {
|
|
1460
1440
|
try { state.threadPanel.abortController.abort(); } catch (e) {}
|
|
@@ -1462,7 +1442,6 @@ export const getWebUiClientScript = (markedSource: string): string => `
|
|
|
1462
1442
|
state.threadPanel.open = false;
|
|
1463
1443
|
state.threadPanel.threadId = null;
|
|
1464
1444
|
state.threadPanel.parentMessageId = null;
|
|
1465
|
-
state.threadPanel.parentMessage = null;
|
|
1466
1445
|
state.threadPanel.messages = [];
|
|
1467
1446
|
state.threadPanel.isStreaming = false;
|
|
1468
1447
|
state.threadPanel.abortController = null;
|
|
@@ -1491,14 +1470,15 @@ export const getWebUiClientScript = (markedSource: string): string => `
|
|
|
1491
1470
|
const renderActiveTopForThreadPanel = (payload) => {
|
|
1492
1471
|
const conv = payload.conversation || {};
|
|
1493
1472
|
const allMsgs = Array.isArray(conv.messages) ? conv.messages : [];
|
|
1473
|
+
// Show the anchor message + replies. The earlier snapshot is still
|
|
1474
|
+
// part of the thread's context server-side, but the panel only
|
|
1475
|
+
// displays what's relevant: the message you forked on, plus what
|
|
1476
|
+
// came after.
|
|
1494
1477
|
const snapshotLength = (conv.threadMeta && typeof conv.threadMeta.snapshotLength === "number")
|
|
1495
1478
|
? conv.threadMeta.snapshotLength
|
|
1496
1479
|
: allMsgs.length;
|
|
1497
|
-
const
|
|
1498
|
-
|
|
1499
|
-
state.threadPanel.parentMessage = parent;
|
|
1500
|
-
state.threadPanel.messages = replies;
|
|
1501
|
-
renderThreadPanelParent();
|
|
1480
|
+
const startIdx = Math.max(0, snapshotLength - 1);
|
|
1481
|
+
state.threadPanel.messages = allMsgs.slice(startIdx);
|
|
1502
1482
|
renderThreadPanelMessages();
|
|
1503
1483
|
};
|
|
1504
1484
|
|
package/src/web-ui-styles.ts
CHANGED
|
@@ -2227,21 +2227,12 @@ export const WEB_UI_STYLES = `
|
|
|
2227
2227
|
border-radius: 4px;
|
|
2228
2228
|
}
|
|
2229
2229
|
.thread-panel-close:hover { color: var(--fg); }
|
|
2230
|
-
.thread-panel-parent {
|
|
2231
|
-
padding: 12px 16px;
|
|
2232
|
-
border-bottom: 1px solid var(--border);
|
|
2233
|
-
background: var(--bg-bubble-user, rgba(0,0,0,0.02));
|
|
2234
|
-
font-size: 13px;
|
|
2235
|
-
}
|
|
2236
|
-
.thread-panel-parent .message-row {
|
|
2237
|
-
margin: 0;
|
|
2238
|
-
}
|
|
2239
|
-
.thread-panel-parent-empty {
|
|
2240
|
-
color: var(--fg-3);
|
|
2241
|
-
font-style: italic;
|
|
2242
|
-
}
|
|
2243
2230
|
.thread-panel-messages {
|
|
2244
|
-
flex: 1;
|
|
2231
|
+
flex: 1 1 0;
|
|
2232
|
+
/* min-height: 0 is required so this flex item can shrink below its
|
|
2233
|
+
content size — without it, overflow-y:auto never engages because
|
|
2234
|
+
the element grows to fit all messages instead of scrolling. */
|
|
2235
|
+
min-height: 0;
|
|
2245
2236
|
overflow-y: auto;
|
|
2246
2237
|
padding: 12px 16px;
|
|
2247
2238
|
}
|
package/src/web-ui.ts
CHANGED
|
@@ -211,7 +211,6 @@ ${WEB_UI_STYLES}
|
|
|
211
211
|
<span class="thread-panel-title">Thread</span>
|
|
212
212
|
<button id="thread-panel-close" class="thread-panel-close" title="Close thread">×</button>
|
|
213
213
|
</div>
|
|
214
|
-
<div id="thread-panel-parent" class="thread-panel-parent"></div>
|
|
215
214
|
<div id="thread-panel-messages" class="thread-panel-messages messages"></div>
|
|
216
215
|
<form id="thread-composer" class="composer thread-composer">
|
|
217
216
|
<div class="composer-inner">
|