@springbrand/agent-runtime 0.2.0-alpha.52 → 0.2.0-alpha.54
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/package.json +2 -2
- package/src/kernel/state.ts +1 -0
- package/src/lib/prompt.ts +3 -3
- package/src/pi/tool/base.ts +1 -1
- package/src/pi/tool/core-host.ts +3 -1
- package/src/runtime.ts +20 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@springbrand/agent-runtime",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.54",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"src",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"@cloudflare/codemode": "0.5.1",
|
|
21
21
|
"@cloudflare/sandbox": "0.12.4",
|
|
22
22
|
"@cloudflare/shell": "0.4.3",
|
|
23
|
-
"@cloudflare/think": "0.
|
|
23
|
+
"@cloudflare/think": "0.17.0",
|
|
24
24
|
"@earendil-works/pi-agent-core": "0.83.0",
|
|
25
25
|
"@earendil-works/pi-ai": "0.83.0",
|
|
26
26
|
"@types/lodash-es": "^4.17.12",
|
package/src/kernel/state.ts
CHANGED
|
@@ -59,6 +59,7 @@ export interface RuntimeQueuedSubmission {
|
|
|
59
59
|
export interface RuntimeTurnState {
|
|
60
60
|
activeSubmissionId?: string;
|
|
61
61
|
activeRequestId?: string;
|
|
62
|
+
activeMessageId?: string;
|
|
62
63
|
recoveryAttempt?: number;
|
|
63
64
|
recoveryMax?: number;
|
|
64
65
|
recoveryReason?: "no_meaningful_model_progress" | "transient_model_error";
|
package/src/lib/prompt.ts
CHANGED
|
@@ -113,9 +113,9 @@ export const INTERACTION =
|
|
|
113
113
|
"a bounded choice; for required free text, omit the options field entirely — never pass an empty or single-item options array; " +
|
|
114
114
|
"continue the same turn when its result arrives. " +
|
|
115
115
|
"Don't use it when a sensible default lets you proceed. " +
|
|
116
|
-
"After completing a substantive task (report, analysis, multi-step job)
|
|
117
|
-
"
|
|
118
|
-
"write
|
|
116
|
+
"After completing a substantive task (report, analysis, multi-step job), finish all work and other Tool calls, " +
|
|
117
|
+
"then call suggest_followups (2-4 directions) as the last Tool call before your final answer. " +
|
|
118
|
+
"After it returns, write your complete final answer and make no further Tool calls. Never for small talk or while a " +
|
|
119
119
|
"task is still in progress; it is non-blocking, unlike ask_user.";
|
|
120
120
|
|
|
121
121
|
// Separates short always-on memory from indexed long-tail workspace files.
|
package/src/pi/tool/base.ts
CHANGED
|
@@ -300,7 +300,7 @@ export function basePiToolCandidates(
|
|
|
300
300
|
name: "suggest_followups",
|
|
301
301
|
label: "Suggest follow-ups",
|
|
302
302
|
description:
|
|
303
|
-
"Offer the user 2-4 optional follow-up directions after completing a substantive task (a report, an analysis, a multi-step job). Call this at most once,
|
|
303
|
+
"Offer the user 2-4 optional follow-up directions after completing a substantive task (a report, an analysis, a multi-step job). Call this at most once, after all work and other Tool calls are complete. It MUST be the last Tool call before the final answer. After it returns, write the complete final answer and make no further Tool calls. Do NOT call it for small talk, quick answers, or while a task is still in progress.",
|
|
304
304
|
parameters: suggestFollowupsParameters,
|
|
305
305
|
async execute(_toolCallId, input) {
|
|
306
306
|
return result({ noted: true, count: input.items.length });
|
package/src/pi/tool/core-host.ts
CHANGED
|
@@ -80,13 +80,15 @@ export function workspaceStateBackend(
|
|
|
80
80
|
|
|
81
81
|
const SPRINGBRAND_CODE_MODE_POLICY = `## SpringBrand Workspace and Asset Policy
|
|
82
82
|
|
|
83
|
+
Every execute script must explicitly return the data the model needs. Never rely on console.log: console output is deliberately not returned to the model.
|
|
84
|
+
|
|
83
85
|
Use state.* for every Workspace filesystem operation. Workspace file methods do not exist under tools.*.
|
|
84
86
|
|
|
85
87
|
state.writeFileBytes is not available. Use state.writeFile or state.appendFile for sandbox-created text.
|
|
86
88
|
|
|
87
89
|
Bundled Skill resources are not Workspace files. Read text with tools.read_skill_resource, run bundled scripts with tools.run_skill_script, and copy templates or assets with tools.materialize_skill_resource.
|
|
88
90
|
|
|
89
|
-
User Attachments are not Workspace files until copied with tools.
|
|
91
|
+
User Attachments are not Workspace files until copied with tools.copy_attachment_to_workspace({ id }).
|
|
90
92
|
|
|
91
93
|
Never create or write data URLs, base64 image strings, or embedded binary payloads in Code Mode.
|
|
92
94
|
|
package/src/runtime.ts
CHANGED
|
@@ -3424,15 +3424,15 @@ export abstract class AgentRuntimeKernel<
|
|
|
3424
3424
|
* @remarks
|
|
3425
3425
|
* Cloudflare Agents SDK 为每条新 WebSocket 连接调用。
|
|
3426
3426
|
*
|
|
3427
|
-
*
|
|
3428
|
-
*
|
|
3427
|
+
* 先发送已完成 transcript,再让恢复基类独自重建 active assistant,
|
|
3428
|
+
* 使持久化历史和 resumable stream 只有一个生产者。
|
|
3429
3429
|
*/
|
|
3430
3430
|
async onConnect(connection: Connection): Promise<void> {
|
|
3431
3431
|
sendIfOpen(
|
|
3432
3432
|
connection,
|
|
3433
3433
|
json({
|
|
3434
3434
|
type: MessageType.CF_AGENT_CHAT_MESSAGES,
|
|
3435
|
-
messages: await this.
|
|
3435
|
+
messages: await this.hydrationMessages(),
|
|
3436
3436
|
}),
|
|
3437
3437
|
);
|
|
3438
3438
|
await super.onConnect(connection);
|
|
@@ -3448,8 +3448,13 @@ export abstract class AgentRuntimeKernel<
|
|
|
3448
3448
|
* 避免在这里复制 Agents SDK 的默认协议行为。
|
|
3449
3449
|
*/
|
|
3450
3450
|
async onRequest(request: Request): Promise<Response> {
|
|
3451
|
-
|
|
3452
|
-
|
|
3451
|
+
const url = new URL(request.url);
|
|
3452
|
+
if (url.pathname.endsWith("/get-messages")) {
|
|
3453
|
+
return Response.json(
|
|
3454
|
+
url.searchParams.get("view") === "hydration"
|
|
3455
|
+
? await this.hydrationMessages()
|
|
3456
|
+
: await this.getMessages(),
|
|
3457
|
+
);
|
|
3453
3458
|
}
|
|
3454
3459
|
return super.onRequest(request);
|
|
3455
3460
|
}
|
|
@@ -3590,12 +3595,20 @@ export abstract class AgentRuntimeKernel<
|
|
|
3590
3595
|
* @remarks
|
|
3591
3596
|
* 新连接、HTTP 读取、Turn 完成投影和 RPC 调用方需要消息快照时调用。
|
|
3592
3597
|
*
|
|
3593
|
-
* 统一从 transcript
|
|
3598
|
+
* 统一从 transcript 生成完整视图;HTTP fallback、fork 和 RPC 读取保留 active assistant。
|
|
3594
3599
|
*/
|
|
3595
3600
|
async getMessages(): Promise<UIMessage[]> {
|
|
3596
3601
|
return this.transcript.browserMessages();
|
|
3597
3602
|
}
|
|
3598
3603
|
|
|
3604
|
+
private async hydrationMessages(): Promise<UIMessage[]> {
|
|
3605
|
+
const messages = await this.getMessages();
|
|
3606
|
+
const running = this.db.submissions.findRunning();
|
|
3607
|
+
return running?.assistantMessageId
|
|
3608
|
+
? messages.filter(({ id }) => id !== running.assistantMessageId)
|
|
3609
|
+
: messages;
|
|
3610
|
+
}
|
|
3611
|
+
|
|
3599
3612
|
/** 读取当前 canonical transcript 中最后一条助手文本。 */
|
|
3600
3613
|
protected async latestAssistantText(): Promise<string | undefined> {
|
|
3601
3614
|
const message = [...await this.transcript.canonicalMessages()]
|
|
@@ -4633,6 +4646,7 @@ export abstract class AgentRuntimeKernel<
|
|
|
4633
4646
|
...(current
|
|
4634
4647
|
? {
|
|
4635
4648
|
activeSubmissionId: current.submissionId,
|
|
4649
|
+
activeMessageId: current.assistantMessageId,
|
|
4636
4650
|
...(current.requestId
|
|
4637
4651
|
? { activeRequestId: current.requestId }
|
|
4638
4652
|
: {}),
|