@poncho-ai/harness 0.50.1 → 0.50.3
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 +5 -5
- package/CHANGELOG.md +31 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +3 -2
- package/package.json +1 -1
- package/src/harness.ts +22 -5
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @poncho-ai/harness@0.50.
|
|
2
|
+
> @poncho-ai/harness@0.50.3 build /home/runner/work/poncho-ai/poncho-ai/packages/harness
|
|
3
3
|
> node scripts/embed-docs.js && tsup src/index.ts --format esm --dts
|
|
4
4
|
|
|
5
5
|
[embed-docs] Generated poncho-docs.ts with 4 topics
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
[34mCLI[39m tsup v8.5.1
|
|
9
9
|
[34mCLI[39m Target: es2022
|
|
10
10
|
[34mESM[39m Build start
|
|
11
|
-
[32mESM[39m [1mdist/index.js [22m[32m530.
|
|
11
|
+
[32mESM[39m [1mdist/index.js [22m[32m530.79 KB[39m
|
|
12
12
|
[32mESM[39m [1mdist/isolate-BNQ6P3HI.js [22m[32m51.41 KB[39m
|
|
13
|
-
[32mESM[39m ⚡️ Build success in
|
|
13
|
+
[32mESM[39m ⚡️ Build success in 229ms
|
|
14
14
|
[34mDTS[39m Build start
|
|
15
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[32m89.
|
|
15
|
+
[32mDTS[39m ⚡️ Build success in 7430ms
|
|
16
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m89.60 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# @poncho-ai/harness
|
|
2
2
|
|
|
3
|
+
## 0.50.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`a67fb45`](https://github.com/cesr/poncho-ai/commit/a67fb45162823d832296ae9af137eb566d9f2f97) Thanks [@cesr](https://github.com/cesr)! - harness: forward `tenantId` through `continueFromToolResult`. Resumed runs (after an approval checkpoint) ran tools with `ctx.tenantId` undefined, so tenant-scoped stores (memory, VFS, todos) resolved the default `"__default__"` tenant instead of the caller's — surfacing as `memory_main_get` returning empty after an approval resume.
|
|
8
|
+
|
|
9
|
+
## 0.50.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#133](https://github.com/cesr/poncho-ai/pull/133) [`60e21c8`](https://github.com/cesr/poncho-ai/commit/60e21c8c18054d2824cf7364b71dabfd07574b48) Thanks [@cesr](https://github.com/cesr)! - harness: don't inject the "interrupted by a time limit" bridge when resuming from tool results
|
|
14
|
+
|
|
15
|
+
A taskless `run()` (continuation checkpoint, or `continueFromToolResult` —
|
|
16
|
+
e.g. resuming after an approval gate) injected a synthetic user message
|
|
17
|
+
telling the model its turn was "interrupted by a time limit ... continue
|
|
18
|
+
EXACTLY from where you left off, do not re-summarize." That bridge is only
|
|
19
|
+
appropriate when the model was actually cut off mid-response (the last
|
|
20
|
+
message is an `assistant` turn, which some providers also reject as a
|
|
21
|
+
conversation-ending message).
|
|
22
|
+
|
|
23
|
+
When the last message is a `tool` result — which is the case for every
|
|
24
|
+
`continueFromToolResult` resume — the conversation already ends in a
|
|
25
|
+
provider-valid user `tool_result` block and the model continues from the
|
|
26
|
+
results naturally. Injecting the bridge there was a bug: after a normal
|
|
27
|
+
approval resolution the model was told its turn had been killed by a time
|
|
28
|
+
limit, causing it to distrust and re-derive context (re-reading the VFS,
|
|
29
|
+
concluding it had "hallucinated" data it had legitimately loaded). The
|
|
30
|
+
bridge is now only added when the last message is an `assistant` turn, and
|
|
31
|
+
its wording no longer hard-codes "time limit" (max-steps checkpoints use
|
|
32
|
+
the same path).
|
|
33
|
+
|
|
3
34
|
## 0.50.1
|
|
4
35
|
|
|
5
36
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1434,6 +1434,11 @@ declare class AgentHarness {
|
|
|
1434
1434
|
error?: string;
|
|
1435
1435
|
}>;
|
|
1436
1436
|
conversationId?: string;
|
|
1437
|
+
/** Must be forwarded for the continuation run, otherwise tenant-scoped
|
|
1438
|
+
* tool stores (memory, VFS, todos) resolve the default "__default__"
|
|
1439
|
+
* tenant on resume instead of the caller's — e.g. memory_main_get
|
|
1440
|
+
* returns empty after an approval checkpoint. */
|
|
1441
|
+
tenantId?: string;
|
|
1437
1442
|
parameters?: Record<string, unknown>;
|
|
1438
1443
|
abortSignal?: AbortSignal;
|
|
1439
1444
|
}): AsyncGenerator<AgentEvent>;
|
package/dist/index.js
CHANGED
|
@@ -10441,10 +10441,10 @@ ${this.skillFingerprint}`;
|
|
|
10441
10441
|
}
|
|
10442
10442
|
} else {
|
|
10443
10443
|
const lastMsg = messages[messages.length - 1];
|
|
10444
|
-
if (lastMsg && lastMsg.role
|
|
10444
|
+
if (lastMsg && lastMsg.role === "assistant") {
|
|
10445
10445
|
messages.push({
|
|
10446
10446
|
role: "user",
|
|
10447
|
-
content: "[System: Your previous turn was interrupted
|
|
10447
|
+
content: "[System: Your previous turn was interrupted before you finished. Your partial response above is already visible to the user. Continue EXACTLY from where you left off \u2014 do NOT restart, re-summarize, or repeat any content you already produced. If you were mid-sentence or mid-table, continue that sentence or table. Proceed directly with the next action or output.]",
|
|
10448
10448
|
metadata: { timestamp: now(), id: randomUUID5() }
|
|
10449
10449
|
});
|
|
10450
10450
|
}
|
|
@@ -11568,6 +11568,7 @@ ${this.skillFingerprint}`;
|
|
|
11568
11568
|
yield* this.runWithTelemetry({
|
|
11569
11569
|
messages,
|
|
11570
11570
|
conversationId: input.conversationId,
|
|
11571
|
+
tenantId: input.tenantId,
|
|
11571
11572
|
parameters: input.parameters,
|
|
11572
11573
|
abortSignal: input.abortSignal
|
|
11573
11574
|
});
|
package/package.json
CHANGED
package/src/harness.ts
CHANGED
|
@@ -2388,14 +2388,25 @@ Code is wrapped in an async IIFE — use \`return\` to return a value to the too
|
|
|
2388
2388
|
});
|
|
2389
2389
|
}
|
|
2390
2390
|
} else {
|
|
2391
|
-
//
|
|
2392
|
-
//
|
|
2393
|
-
//
|
|
2391
|
+
// Taskless run: either a genuine continuation checkpoint (the model
|
|
2392
|
+
// was cut off mid-response by a soft-deadline / max-steps boundary)
|
|
2393
|
+
// or a tool-result resume — `continueFromToolResult`, e.g. after an
|
|
2394
|
+
// approval gate — whose last message is the tool results.
|
|
2395
|
+
//
|
|
2396
|
+
// Only the first case needs a bridge: ending on an assistant message
|
|
2397
|
+
// is invalid for some providers (Anthropic), and the model must be
|
|
2398
|
+
// told to continue rather than restart. A `tool` last message converts
|
|
2399
|
+
// to a user-role tool_result block, so the conversation already ends
|
|
2400
|
+
// "with a user message" and the model continues from the results
|
|
2401
|
+
// naturally. Injecting the bridge after tool results was a bug: it
|
|
2402
|
+
// told the model — after a normal approval resolution — that its turn
|
|
2403
|
+
// had been "interrupted by a time limit" and to not re-summarize,
|
|
2404
|
+
// which made it distrust and re-derive context it already had.
|
|
2394
2405
|
const lastMsg = messages[messages.length - 1];
|
|
2395
|
-
if (lastMsg && lastMsg.role
|
|
2406
|
+
if (lastMsg && lastMsg.role === "assistant") {
|
|
2396
2407
|
messages.push({
|
|
2397
2408
|
role: "user",
|
|
2398
|
-
content: "[System: Your previous turn was interrupted
|
|
2409
|
+
content: "[System: Your previous turn was interrupted before you finished. Your partial response above is already visible to the user. Continue EXACTLY from where you left off — do NOT restart, re-summarize, or repeat any content you already produced. If you were mid-sentence or mid-table, continue that sentence or table. Proceed directly with the next action or output.]",
|
|
2399
2410
|
metadata: { timestamp: now(), id: randomUUID() },
|
|
2400
2411
|
});
|
|
2401
2412
|
}
|
|
@@ -3716,6 +3727,11 @@ Code is wrapped in an async IIFE — use \`return\` to return a value to the too
|
|
|
3716
3727
|
messages: Message[];
|
|
3717
3728
|
toolResults: Array<{ callId: string; toolName: string; result?: unknown; error?: string }>;
|
|
3718
3729
|
conversationId?: string;
|
|
3730
|
+
/** Must be forwarded for the continuation run, otherwise tenant-scoped
|
|
3731
|
+
* tool stores (memory, VFS, todos) resolve the default "__default__"
|
|
3732
|
+
* tenant on resume instead of the caller's — e.g. memory_main_get
|
|
3733
|
+
* returns empty after an approval checkpoint. */
|
|
3734
|
+
tenantId?: string;
|
|
3719
3735
|
parameters?: Record<string, unknown>;
|
|
3720
3736
|
abortSignal?: AbortSignal;
|
|
3721
3737
|
}): AsyncGenerator<AgentEvent> {
|
|
@@ -3773,6 +3789,7 @@ Code is wrapped in an async IIFE — use \`return\` to return a value to the too
|
|
|
3773
3789
|
yield* this.runWithTelemetry({
|
|
3774
3790
|
messages,
|
|
3775
3791
|
conversationId: input.conversationId,
|
|
3792
|
+
tenantId: input.tenantId,
|
|
3776
3793
|
parameters: input.parameters,
|
|
3777
3794
|
abortSignal: input.abortSignal,
|
|
3778
3795
|
});
|