@springbrand/agent-runtime 0.3.0-alpha.7 → 0.3.0-alpha.9
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/adapter/cloudflare/agent.ts +4 -7
- package/src/adapter/cloudflare/define-agent.ts +2 -0
- package/src/adapter/cloudflare/schema.ts +3 -0
- package/src/adapter/cloudflare/subagent/definition.ts +4 -4
- package/src/adapter/cloudflare/subagent/runner.ts +1 -1
- package/src/adapter/cloudflare/subagent/tools.ts +2 -2
- package/src/adapter/cloudflare/universal-agent/preparation.ts +3 -3
- package/src/adapter/cloudflare/universal-agent/tools.ts +4 -6
- package/src/adapter/cloudflare/workspace/version-control.ts +1 -1
- package/src/config/agent-context.ts +1 -1
- package/src/config/assembler.ts +17 -31
- package/src/config/assembly-snapshot.ts +1 -1
- package/src/config/definition.ts +1 -1
- package/src/config/model-guidance.ts +1 -1
- package/src/config/ports.ts +5 -15
- package/src/config/public-contracts.ts +2 -2
- package/src/context/extension/assembly.ts +2 -2
- package/src/context/memory/budget/gate.ts +1 -1
- package/src/conversation/state.ts +1 -1
- package/src/index.ts +7 -7
- package/src/lib/execution-level.ts +13 -0
- package/src/lib/prompt.ts +3 -5
- package/src/models/index.ts +1 -0
- package/src/session/cloudflare/migration.ts +29 -8
- package/src/skills/springbrand-worker-website/index.ts +1 -1
- package/src/submission/admission.ts +4 -0
- package/src/submission/delivery.ts +1 -1
- package/src/submission/finalization.ts +1 -1
- package/src/submission/repository.ts +8 -1
- package/src/telemetry/coordinator.ts +1 -1
- package/src/telemetry/subagent-lifecycle.ts +1 -1
- package/src/telemetry/turn-events.ts +1 -1
- package/src/tools/README.md +44 -0
- package/src/tools/{ai-adapter.ts → adapters/ai-to-pi.ts} +6 -9
- package/src/tools/{declared.ts → adapters/declared.ts} +2 -2
- package/src/tools/{nested-tools.ts → adapters/pi-to-ai.ts} +2 -2
- package/src/tools/assistant/ask-user.ts +317 -0
- package/src/tools/assistant/candidate.ts +15 -0
- package/src/tools/assistant/followups.ts +34 -0
- package/src/tools/assistant/index.ts +19 -0
- package/src/tools/assistant/memory.ts +73 -0
- package/src/tools/assistant/plan.ts +98 -0
- package/src/tools/{time.ts → assistant/time.ts} +1 -1
- package/src/tools/{core-host.ts → codemode/adapter.ts} +50 -49
- package/src/tools/{core.ts → codemode/index.ts} +36 -92
- package/src/tools/codemode/workspace-connector.ts +198 -0
- package/src/tools/extension/index.ts +42 -0
- package/src/tools/index.ts +28 -26
- package/src/tools/{gateway.ts → mcp/gateway.ts} +19 -19
- package/src/tools/{mcp.ts → mcp/index.ts} +5 -5
- package/src/tools/{approval → runtime/approval}/repository.ts +3 -9
- package/src/tools/{compiler.ts → runtime/compiler.ts} +24 -155
- package/src/tools/runtime/contracts.ts +117 -0
- package/src/tools/{decision-gate.ts → runtime/decision-gate.ts} +36 -61
- package/src/tools/{human-decisions.ts → runtime/human-decisions.ts} +4 -4
- package/src/tools/{interaction → runtime/interaction}/repository.ts +1 -7
- package/src/tools/runtime/result.ts +22 -0
- package/src/tools/sandbox/index.ts +228 -0
- package/src/tools/{schedule.ts → schedule/index.ts} +50 -49
- package/src/tools/skill/contracts.ts +20 -0
- package/src/tools/skill/index.ts +99 -0
- package/src/tools/skill/resources.ts +322 -0
- package/src/tools/skill/scripts.ts +168 -0
- package/src/tools/{subagent-authority.ts → subagent/authority.ts} +31 -31
- package/src/tools/{subagent.ts → subagent/index.ts} +34 -37
- package/src/tools/{subagent-run-repository.ts → subagent/repository.ts} +1 -1
- package/src/tools/{subagent-runtime.ts → subagent/runtime.ts} +1 -1
- package/src/tools/{temporary-agent → subagent/temporary}/approvals.ts +4 -7
- package/src/tools/{temporary-agent → subagent/temporary}/core.ts +1 -1
- package/src/tools/{temporary-agent → subagent/temporary}/runner.ts +1 -1
- package/src/tools/{temporary-agent → subagent/temporary}/workspace.ts +1 -4
- package/src/tools/{web-fetch.ts → web/fetch.ts} +4 -13
- package/src/tools/web/index.ts +2 -0
- package/src/tools/web/search/api.ts +1320 -0
- package/src/tools/web/search/index.ts +2 -0
- package/src/tools/{web-search/web-search.ts → web/search/search.ts} +5 -7
- package/src/tools/{workspace-sandbox.ts → workspace/index.ts} +12 -272
- package/src/tools/{workspace-revision.ts → workspace/revision.ts} +3 -3
- package/src/tools/base.ts +0 -542
- package/src/tools/skill.ts +0 -565
- package/src/tools/web-search/api.ts +0 -1318
- package/src/tools/web-search/index.ts +0 -2
- package/src/tools/workspace-state-connector.ts +0 -146
- package/src/tools/{approval → runtime/approval}/index.ts +0 -0
- package/src/tools/{interaction → runtime/interaction}/index.ts +0 -0
- package/src/tools/{unattended-error.ts → runtime/unattended-error.ts} +0 -0
- package/src/tools/{temporary-agent → subagent/temporary}/coordinator.ts +0 -0
- package/src/tools/{subagent-types → subagent/types}/contract.ts +0 -0
- package/src/tools/{subagent-types → subagent/types}/extract/index.ts +0 -0
- package/src/tools/{subagent-types → subagent/types}/fanout/index.ts +0 -0
- package/src/tools/{subagent-types → subagent/types}/registry.ts +1 -1
- /package/src/tools/{workspace-versioning.ts → workspace/versioning.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@springbrand/agent-runtime",
|
|
3
|
-
"version": "0.3.0-alpha.
|
|
3
|
+
"version": "0.3.0-alpha.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"src",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
".": "./src/index.ts",
|
|
14
14
|
"./adapter/cloudflare": "./src/adapter/cloudflare/index.ts",
|
|
15
15
|
"./contracts": "./src/config/public-contracts.ts",
|
|
16
|
-
"./declared-tool": "./src/tools/declared.ts",
|
|
16
|
+
"./declared-tool": "./src/tools/adapters/declared.ts",
|
|
17
17
|
"./models": "./src/lib/model-catalog.ts"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
@@ -36,7 +36,6 @@ import {
|
|
|
36
36
|
type RuntimeUnattendedExecutionGrant,
|
|
37
37
|
} from "../../submission";
|
|
38
38
|
import type { ExecutionLevel } from "../../lib/execution-level";
|
|
39
|
-
import { pinnedUnattendedExecutionGrant } from "../../submission/unattended";
|
|
40
39
|
import {
|
|
41
40
|
HarnessRuntimeConfig,
|
|
42
41
|
activateRuntimeCandidate,
|
|
@@ -798,7 +797,7 @@ export abstract class AgentRuntimeKernel<
|
|
|
798
797
|
requestId: submission.requestId,
|
|
799
798
|
executionLevel: activeRuntime.snapshot.profile.executionLevel,
|
|
800
799
|
origin: submission.origin,
|
|
801
|
-
|
|
800
|
+
scheduledMaxExecutionLevel: submission.scheduledMaxExecutionLevel ?? undefined,
|
|
802
801
|
},
|
|
803
802
|
candidates: harnessInput.candidates,
|
|
804
803
|
telemetry: this.telemetry,
|
|
@@ -826,8 +825,6 @@ export abstract class AgentRuntimeKernel<
|
|
|
826
825
|
}
|
|
827
826
|
},
|
|
828
827
|
gateTool: harnessInput.platform.gateTool,
|
|
829
|
-
authorizeUnattendedExecution:
|
|
830
|
-
harnessInput.platform.authorizeUnattendedExecution,
|
|
831
828
|
onUnattendedFailure: (reason) => {
|
|
832
829
|
this.db.submissions.recordUnattendedFailure(submissionId, reason);
|
|
833
830
|
},
|
|
@@ -1431,6 +1428,8 @@ export abstract class AgentRuntimeKernel<
|
|
|
1431
1428
|
prompt: string,
|
|
1432
1429
|
options?: {
|
|
1433
1430
|
idempotencyKey?: string;
|
|
1431
|
+
scheduledMaxExecutionLevel?: ExecutionLevel;
|
|
1432
|
+
/** @deprecated Retained for rolling upgrades; ignored by Runtime. */
|
|
1434
1433
|
unattendedExecutionGrant?: RuntimeUnattendedExecutionGrant;
|
|
1435
1434
|
},
|
|
1436
1435
|
): Promise<SubmissionReceipt> {
|
|
@@ -1445,9 +1444,7 @@ export abstract class AgentRuntimeKernel<
|
|
|
1445
1444
|
requestId,
|
|
1446
1445
|
idempotencyKey: options?.idempotencyKey,
|
|
1447
1446
|
origin: "scheduled",
|
|
1448
|
-
|
|
1449
|
-
? pinnedUnattendedExecutionGrant(options.unattendedExecutionGrant)
|
|
1450
|
-
: undefined,
|
|
1447
|
+
scheduledMaxExecutionLevel: options?.scheduledMaxExecutionLevel,
|
|
1451
1448
|
},
|
|
1452
1449
|
SCHEDULED_STABLE_TIMEOUT_MS,
|
|
1453
1450
|
);
|
|
@@ -264,6 +264,8 @@ export interface RuntimeAgentControls {
|
|
|
264
264
|
prompt: string,
|
|
265
265
|
opts?: {
|
|
266
266
|
idempotencyKey?: string;
|
|
267
|
+
scheduledMaxExecutionLevel?: import("../../lib/execution-level").ExecutionLevel;
|
|
268
|
+
/** @deprecated Retained for rolling upgrades; ignored by Runtime. */
|
|
267
269
|
unattendedExecutionGrant?: import("../../submission").RuntimeUnattendedExecutionGrant;
|
|
268
270
|
},
|
|
269
271
|
): Promise<SubmissionReceipt>;
|
|
@@ -54,6 +54,9 @@ export function initializeSchema(sql: SqlTaggedTemplate): void {
|
|
|
54
54
|
if (!submissionColumns.has("origin")) {
|
|
55
55
|
sql`ALTER TABLE pi_submissions ADD COLUMN origin TEXT NOT NULL DEFAULT 'user'`;
|
|
56
56
|
}
|
|
57
|
+
if (!submissionColumns.has("scheduled_max_execution_level")) {
|
|
58
|
+
sql`ALTER TABLE pi_submissions ADD COLUMN scheduled_max_execution_level TEXT`;
|
|
59
|
+
}
|
|
57
60
|
if (!submissionColumns.has("unattended_execution_grant_json")) {
|
|
58
61
|
sql`ALTER TABLE pi_submissions ADD COLUMN unattended_execution_grant_json TEXT`;
|
|
59
62
|
}
|
|
@@ -11,8 +11,8 @@ import type { HarnessEvent } from "@earendil-works/pi-agent-core";
|
|
|
11
11
|
import type { UIMessageChunk } from "ai";
|
|
12
12
|
import {
|
|
13
13
|
AGENT_TYPES,
|
|
14
|
-
} from "../../../tools/subagent
|
|
15
|
-
import type { AgentType } from "../../../tools/subagent
|
|
14
|
+
} from "../../../tools/subagent/types/registry";
|
|
15
|
+
import type { AgentType } from "../../../tools/subagent/types/contract";
|
|
16
16
|
import type {
|
|
17
17
|
RuntimeProviderPort,
|
|
18
18
|
WorkspacePort,
|
|
@@ -30,8 +30,8 @@ import {
|
|
|
30
30
|
decodeSubagentCompletion,
|
|
31
31
|
emptySubagentUsage,
|
|
32
32
|
encodeSubagentCompletion,
|
|
33
|
-
} from "../../../tools/subagent
|
|
34
|
-
import type { RuntimeSubagentUsageMetrics } from "../../../tools/subagent
|
|
33
|
+
} from "../../../tools/subagent/runtime";
|
|
34
|
+
import type { RuntimeSubagentUsageMetrics } from "../../../tools/subagent/authority";
|
|
35
35
|
import { createCloudflareSubAgentTools } from "./tools";
|
|
36
36
|
|
|
37
37
|
type RunStatus =
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
import type { Api, AssistantMessage, Model, Models } from "@earendil-works/pi-ai";
|
|
13
13
|
import { z } from "zod";
|
|
14
14
|
import { assembleSubagentPrompt } from "../../../lib/prompt";
|
|
15
|
-
import type { AgentType } from "../../../tools/subagent
|
|
15
|
+
import type { AgentType } from "../../../tools/subagent/types/contract";
|
|
16
16
|
import { structuredOutputStream } from "../../../models";
|
|
17
17
|
import {
|
|
18
18
|
openSessionHarness,
|
|
@@ -15,13 +15,13 @@ import type {
|
|
|
15
15
|
} from "@earendil-works/pi-agent-core";
|
|
16
16
|
import { Type } from "@earendil-works/pi-ai";
|
|
17
17
|
import type { WorkspacePort } from "../../../config/ports";
|
|
18
|
-
import type { AgentType } from "../../../tools/subagent
|
|
18
|
+
import type { AgentType } from "../../../tools/subagent/types/contract";
|
|
19
19
|
import {
|
|
20
20
|
compileHarnessTools,
|
|
21
21
|
type CompileHarnessToolsOptions,
|
|
22
22
|
type PiToolCandidate,
|
|
23
23
|
} from "../../../tools";
|
|
24
|
-
import { workspacePiToolCandidates } from "../../../tools/workspace
|
|
24
|
+
import { workspacePiToolCandidates } from "../../../tools/workspace";
|
|
25
25
|
|
|
26
26
|
const READONLY_WORKSPACE_TOOLS = new Set([
|
|
27
27
|
"read",
|
|
@@ -9,16 +9,16 @@ import type {
|
|
|
9
9
|
RuntimeSubagentPort,
|
|
10
10
|
WorkspacePort,
|
|
11
11
|
} from "../../../config/ports";
|
|
12
|
-
import { decodeSubagentCompletion } from "../../../tools/subagent
|
|
12
|
+
import { decodeSubagentCompletion } from "../../../tools/subagent/runtime";
|
|
13
13
|
import type { RuntimeDegradation } from "../../../config/degradation";
|
|
14
14
|
import type { RuntimeMemoryProfile } from "../../../config/profile";
|
|
15
|
-
import { AGENT_TYPES } from "../../../tools/subagent
|
|
15
|
+
import { AGENT_TYPES } from "../../../tools/subagent/types/registry";
|
|
16
16
|
import type { RuntimeAgentConfigContext } from "../../../config/agent-context";
|
|
17
17
|
import {
|
|
18
18
|
createBrowserExecutionFactory,
|
|
19
19
|
createWorkspaceCodeExecutionFactory,
|
|
20
20
|
type RuntimeBrowserBinding,
|
|
21
|
-
} from "../../../tools/
|
|
21
|
+
} from "../../../tools/codemode/adapter";
|
|
22
22
|
import {
|
|
23
23
|
createCloudflareSandboxAdapter,
|
|
24
24
|
type SandboxAdmission,
|
|
@@ -7,15 +7,13 @@ import type {
|
|
|
7
7
|
} from "../../../config/ports";
|
|
8
8
|
import type { RuntimeDegradation } from "../../../config/degradation";
|
|
9
9
|
import type { RuntimeMemoryProfile } from "../../../config/profile";
|
|
10
|
-
import type { WorkspaceRevisionRestorePort } from "../../../tools/workspace
|
|
10
|
+
import type { WorkspaceRevisionRestorePort } from "../../../tools/workspace/versioning";
|
|
11
11
|
import { schedulePiToolCandidates } from "../../../tools/schedule";
|
|
12
|
-
import { workspaceRevisionPiToolCandidate } from "../../../tools/workspace
|
|
13
|
-
import {
|
|
14
|
-
sandboxPiToolCandidates,
|
|
15
|
-
} from "../../../tools/workspace-sandbox";
|
|
12
|
+
import { workspaceRevisionPiToolCandidate } from "../../../tools/workspace/revision";
|
|
13
|
+
import { sandboxPiToolCandidates } from "../../../tools/sandbox";
|
|
16
14
|
import type { RuntimeCodeExecutionFactory } from "../../../config/ports";
|
|
17
15
|
import type { ToolAssemblyResult } from "../../../config/definition";
|
|
18
|
-
import type { PiToolCandidate } from "../../../tools/
|
|
16
|
+
import type { PiToolCandidate } from "../../../tools/runtime/contracts";
|
|
19
17
|
|
|
20
18
|
export function assembleUniversalAgentTools(options: {
|
|
21
19
|
hostTools?: readonly PiToolCandidate[];
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
type WorkspaceRevision,
|
|
6
6
|
type WorkspaceRevisionManifest,
|
|
7
7
|
type WorkspaceVersionPort,
|
|
8
|
-
} from "../../../tools/workspace
|
|
8
|
+
} from "../../../tools/workspace/versioning";
|
|
9
9
|
import { createWorkspaceGitFs } from "./git-fs";
|
|
10
10
|
|
|
11
11
|
const PAGE_SIZE = 256;
|
package/src/config/assembler.ts
CHANGED
|
@@ -37,10 +37,7 @@ import {
|
|
|
37
37
|
type PiRuntimeAssembly,
|
|
38
38
|
} from "./assembly-snapshot";
|
|
39
39
|
import type { AgentTool } from "@earendil-works/pi-agent-core";
|
|
40
|
-
import type {
|
|
41
|
-
PiToolCandidate,
|
|
42
|
-
ToolExposureMode,
|
|
43
|
-
} from "../tools/compiler";
|
|
40
|
+
import type { PiToolCandidate, ToolExposureMode } from "../tools/runtime/contracts";
|
|
44
41
|
import type {
|
|
45
42
|
AssembleRuntimeSnapshotInput,
|
|
46
43
|
RuntimeSettings,
|
|
@@ -51,17 +48,11 @@ import type {
|
|
|
51
48
|
RuntimeToolSurfacePolicy,
|
|
52
49
|
} from "./definition";
|
|
53
50
|
import type { RuntimeCodeExecutionFactory } from "./ports";
|
|
54
|
-
import {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
} from "../tools/base";
|
|
58
|
-
import {
|
|
59
|
-
BROWSER_EXECUTE_TOOL_NAME,
|
|
60
|
-
browserExecutionPiToolCandidate,
|
|
61
|
-
codeExecutionPiToolCandidate,
|
|
62
|
-
} from "../tools/core";
|
|
51
|
+
import { basePiToolCandidates } from "../tools/assistant";
|
|
52
|
+
import { memoryPiToolCandidate } from "../tools/assistant/memory";
|
|
53
|
+
import { BROWSER_EXECUTE_TOOL_NAME, browserExecutionPiToolCandidate, codeExecutionPiToolCandidate } from "../tools/codemode";
|
|
63
54
|
import { skillPiToolCandidates } from "../tools/skill";
|
|
64
|
-
import { createWebSearch, WEB_SEARCH_MODEL } from "../tools/web
|
|
55
|
+
import { createWebSearch, WEB_SEARCH_MODEL } from "../tools/web/search";
|
|
65
56
|
import { subagentPiToolCandidates } from "../tools/subagent";
|
|
66
57
|
import { resolvePiModel } from "../models";
|
|
67
58
|
import {
|
|
@@ -305,17 +296,12 @@ async function createToolSurface(
|
|
|
305
296
|
typeof candidate.tool.execute === "function",
|
|
306
297
|
);
|
|
307
298
|
const codeExecutionCandidates = Object.freeze([...mergeable]);
|
|
308
|
-
const codeExecutionToolNames = new Set(
|
|
309
|
-
codeExecutionCandidates.map(({ tool }) => tool.name),
|
|
310
|
-
);
|
|
311
299
|
const codeExecution = input.codeExecution.create(
|
|
312
300
|
codeExecutionCandidates,
|
|
313
301
|
);
|
|
314
|
-
const
|
|
315
|
-
({ tool }) => !codeExecutionToolNames.has(tool.name),
|
|
316
|
-
);
|
|
302
|
+
const directToolNames = new Set(directVisible.map(({ tool }) => tool.name));
|
|
317
303
|
const routeList = (deferred: boolean) => {
|
|
318
|
-
const matches =
|
|
304
|
+
const matches = directVisible.filter((candidate) =>
|
|
319
305
|
(defersTool?.(candidate.tool.name) === true) === deferred
|
|
320
306
|
);
|
|
321
307
|
return matches.length > 0
|
|
@@ -327,8 +313,9 @@ async function createToolSurface(
|
|
|
327
313
|
};
|
|
328
314
|
const routeGuidance = [
|
|
329
315
|
"## Tool routing",
|
|
330
|
-
"
|
|
316
|
+
"For top-level deferred Tools, use Provider Tool Search with their exact name, then call them directly.",
|
|
331
317
|
"Top-level immediate Tools are already available outside execute; call them directly.",
|
|
318
|
+
"Only Code Mode Tools listed below are callable inside execute through tools.<name>. Tools marked execute-only are not registered as top-level Tools.",
|
|
332
319
|
"",
|
|
333
320
|
"## Top-level deferred Tools",
|
|
334
321
|
routeList(true),
|
|
@@ -336,21 +323,20 @@ async function createToolSurface(
|
|
|
336
323
|
"## Top-level immediate Tools",
|
|
337
324
|
routeList(false),
|
|
338
325
|
"",
|
|
326
|
+
"## Code Mode Tools",
|
|
327
|
+
codeExecutionCandidates.length > 0
|
|
328
|
+
? codeExecutionCandidates.map(({ tool }) =>
|
|
329
|
+
`- \`tools.${tool.name}\` — ${directToolNames.has(tool.name) ? "also available as a top-level Tool" : "execute-only"}`
|
|
330
|
+
).join("\n")
|
|
331
|
+
: "- None.",
|
|
332
|
+
"",
|
|
339
333
|
].join("\n");
|
|
340
|
-
const materializeGuidance = codeExecutionCandidates.some(
|
|
341
|
-
({ tool }) => tool.name === "materialize_skill_resource",
|
|
342
|
-
)
|
|
343
|
-
? "Skill resource copying is available only inside execute through " +
|
|
344
|
-
"`tools.materialize_skill_resource({ name, path, destination })`; " +
|
|
345
|
-
"no Direct Tool is registered for it. " +
|
|
346
|
-
"Copy multiple resources sequentially in one execute so durable replay preserves call order.\n\n"
|
|
347
|
-
: "";
|
|
348
334
|
return Object.freeze({
|
|
349
335
|
candidates: Object.freeze([
|
|
350
336
|
classify(codeExecutionPiToolCandidate({
|
|
351
337
|
...codeExecution,
|
|
352
338
|
description:
|
|
353
|
-
routeGuidance + "\n" +
|
|
339
|
+
routeGuidance + "\n" + codeExecution.description,
|
|
354
340
|
})),
|
|
355
341
|
...directVisible.map(classify),
|
|
356
342
|
]),
|
|
@@ -18,7 +18,7 @@ import type {
|
|
|
18
18
|
import type { RuntimeProviderPort } from "./ports";
|
|
19
19
|
import { assembleSystemPrompt } from "../lib/prompt";
|
|
20
20
|
import { resolvePiModel } from "../models";
|
|
21
|
-
import type { PiToolCandidate } from "../tools/
|
|
21
|
+
import type { PiToolCandidate } from "../tools/runtime/contracts";
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* 收集完动态 Extension/MCP 候选后,一次性生成最终 Tool Surface。
|
package/src/config/definition.ts
CHANGED
|
@@ -17,7 +17,7 @@ import type {
|
|
|
17
17
|
} from "./profile";
|
|
18
18
|
import type { RuntimeExtensionConfig } from "../context/extension/contracts";
|
|
19
19
|
import type { RuntimeDegradation } from "./degradation";
|
|
20
|
-
import type { PiToolCandidate } from "../tools/
|
|
20
|
+
import type { PiToolCandidate } from "../tools/runtime/contracts";
|
|
21
21
|
import type {
|
|
22
22
|
RuntimeAgentContext,
|
|
23
23
|
RuntimeAgentPlanningContext,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Context } from "@earendil-works/pi-ai";
|
|
2
|
-
import type { PiToolCandidate } from "../tools/
|
|
2
|
+
import type { PiToolCandidate } from "../tools/runtime/contracts";
|
|
3
3
|
|
|
4
4
|
/** Only descriptions and guidance may vary inside a pinned Submission. */
|
|
5
5
|
export async function refreshModelGuidance(
|
package/src/config/ports.ts
CHANGED
|
@@ -5,14 +5,13 @@ import type { ScheduleSpec, RuntimeSchedulePreparation } from "../submission/con
|
|
|
5
5
|
import type { RuntimeActivityProjection } from "../conversation/state";
|
|
6
6
|
import type { ExecutionLevel } from "../lib/execution-level";
|
|
7
7
|
import type { AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
8
|
-
import type { PiToolCandidate } from "../tools/
|
|
9
|
-
import type { RuntimeUnattendedExecutionGrant } from "../submission/contracts";
|
|
8
|
+
import type { PiToolCandidate } from "../tools/runtime/contracts";
|
|
10
9
|
import type {
|
|
11
10
|
RuntimeEventConfirmation,
|
|
12
11
|
RuntimeLifecycleFact,
|
|
13
12
|
RuntimeSubagentUsageEvent,
|
|
14
13
|
RuntimeSubagentUsageMetrics,
|
|
15
|
-
} from "../tools/subagent
|
|
14
|
+
} from "../tools/subagent/authority";
|
|
16
15
|
export type { RuntimeModelInputModality } from "./profile";
|
|
17
16
|
export type {
|
|
18
17
|
RuntimeEventConfirmation,
|
|
@@ -23,7 +22,7 @@ export type {
|
|
|
23
22
|
RuntimeSubmissionAdmissionHook,
|
|
24
23
|
RuntimeSubmissionAdmissionInput,
|
|
25
24
|
RuntimeSubmissionAdmissionResult,
|
|
26
|
-
} from "../tools/subagent
|
|
25
|
+
} from "../tools/subagent/authority";
|
|
27
26
|
|
|
28
27
|
// #region Workspace 端口
|
|
29
28
|
|
|
@@ -1039,17 +1038,8 @@ export interface RuntimePlatformPort {
|
|
|
1039
1038
|
* It is called before dispatch and again at the effect boundary so a grant
|
|
1040
1039
|
* revocation cannot be hidden by an earlier decision.
|
|
1041
1040
|
*/
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
capability: string;
|
|
1045
|
-
operation: string;
|
|
1046
|
-
object?: unknown;
|
|
1047
|
-
toolCallId: string;
|
|
1048
|
-
toolName: string;
|
|
1049
|
-
input: unknown;
|
|
1050
|
-
requiredExecutionLevel: ExecutionLevel;
|
|
1051
|
-
signal: AbortSignal;
|
|
1052
|
-
}): Promise<void>;
|
|
1041
|
+
/** @deprecated Scheduled execution is authorized locally by execution level. */
|
|
1042
|
+
authorizeUnattendedExecution?(request: unknown): Promise<void>;
|
|
1053
1043
|
}
|
|
1054
1044
|
|
|
1055
1045
|
/**
|
|
@@ -17,7 +17,7 @@ export * from "../conversation/message";
|
|
|
17
17
|
export * from "../submission/contracts";
|
|
18
18
|
export * from "../conversation/state";
|
|
19
19
|
export * from "../lib/execution-level";
|
|
20
|
-
export type { WorkspaceRevision, WorkspaceRevisionManifest } from "../tools/workspace
|
|
20
|
+
export type { WorkspaceRevision, WorkspaceRevisionManifest } from "../tools/workspace/versioning";
|
|
21
21
|
export type {
|
|
22
22
|
RuntimeEventConfirmation,
|
|
23
23
|
RuntimeLifecycleFact,
|
|
@@ -27,4 +27,4 @@ export type {
|
|
|
27
27
|
RuntimeSubmissionAdmissionHook,
|
|
28
28
|
RuntimeSubmissionAdmissionInput,
|
|
29
29
|
RuntimeSubmissionAdmissionResult,
|
|
30
|
-
} from "../tools/subagent
|
|
30
|
+
} from "../tools/subagent/authority";
|
|
@@ -12,8 +12,8 @@ import type {
|
|
|
12
12
|
import type { RuntimeDegradation } from "../../config/degradation";
|
|
13
13
|
import { withRuntimeLoadTimeout } from "../../config/runtime-load";
|
|
14
14
|
import { sanitizeExtensionName } from "../../lib/extension-name";
|
|
15
|
-
import type { PiToolCandidate } from "../../tools/
|
|
16
|
-
import { createPiDeclaredToolCandidate } from "../../tools/declared";
|
|
15
|
+
import type { PiToolCandidate } from "../../tools/runtime/contracts";
|
|
16
|
+
import { createPiDeclaredToolCandidate } from "../../tools/adapters/declared";
|
|
17
17
|
|
|
18
18
|
export interface PiExtensionContextContribution {
|
|
19
19
|
readonly extensionName: string;
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
/**
|
|
30
30
|
* 持久化单个字符串叶子的上限。
|
|
31
31
|
*
|
|
32
|
-
* MUST ≥ 单页 read 的上限(见 `workspace
|
|
32
|
+
* MUST ≥ 单页 read 的上限(见 `tools/workspace/index.ts` 的 `READ_PAGE_MAX_CHARS`),
|
|
33
33
|
* 否则持久记录会比模型当轮看到的内容还少,会话恢复后出现凭空缺页。
|
|
34
34
|
*/
|
|
35
35
|
export const STORAGE_LEAF_MAX_CHARS = 64 * 1024;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ApprovalReceipt } from "../submission/contracts";
|
|
2
2
|
import type { StoredSubmission } from "../submission/repository";
|
|
3
|
-
import type { PendingApprovalSummary } from "../tools/approval/repository";
|
|
3
|
+
import type { PendingApprovalSummary } from "../tools/runtime/approval/repository";
|
|
4
4
|
import type { PiCanonicalUserInput } from "./message/contract";
|
|
5
5
|
|
|
6
6
|
export type RuntimeLoadPhase = "config" | "assembly" | "mcp" | "pi";
|
package/src/index.ts
CHANGED
|
@@ -51,7 +51,7 @@ export type { RuntimeAssemblyView } from "./config/assembly-view";
|
|
|
51
51
|
export * from "./adapter/cloudflare/define-agent";
|
|
52
52
|
export type { ToolInteractionResponsePreparation } from "./adapter/cloudflare/agent";
|
|
53
53
|
export * from "./conversation/state";
|
|
54
|
-
export * from "./tools/workspace
|
|
54
|
+
export * from "./tools/workspace/versioning";
|
|
55
55
|
export * from "./lib/execution-level";
|
|
56
56
|
export type {
|
|
57
57
|
RuntimeAssemblyInput,
|
|
@@ -84,10 +84,10 @@ export type {
|
|
|
84
84
|
} from "./lib/host-actions";
|
|
85
85
|
export {
|
|
86
86
|
AGENT_TYPES,
|
|
87
|
-
} from "./tools/subagent
|
|
87
|
+
} from "./tools/subagent/types/registry";
|
|
88
88
|
export type {
|
|
89
89
|
AgentType,
|
|
90
|
-
} from "./tools/subagent
|
|
90
|
+
} from "./tools/subagent/types/contract";
|
|
91
91
|
export type {
|
|
92
92
|
PiToolCandidate,
|
|
93
93
|
ToolExposureMode,
|
|
@@ -129,15 +129,15 @@ export type {
|
|
|
129
129
|
TemporaryAgentLaunch,
|
|
130
130
|
TemporaryAgentRequest,
|
|
131
131
|
TemporaryAgentRunContext,
|
|
132
|
-
} from "./tools/temporary
|
|
133
|
-
export { TEMPORARY_AGENT_LAUNCH_KEY } from "./tools/temporary
|
|
132
|
+
} from "./tools/subagent/temporary/core";
|
|
133
|
+
export { TEMPORARY_AGENT_LAUNCH_KEY } from "./tools/subagent/temporary/core";
|
|
134
134
|
export {
|
|
135
135
|
temporaryAgentExtensionIsSafe,
|
|
136
136
|
temporaryAgentToolAllowed,
|
|
137
|
-
} from "./tools/temporary
|
|
137
|
+
} from "./tools/subagent/temporary/runner";
|
|
138
138
|
export {
|
|
139
139
|
createTemporaryAgentWorkspace,
|
|
140
|
-
} from "./tools/temporary
|
|
140
|
+
} from "./tools/subagent/temporary/workspace";
|
|
141
141
|
export {
|
|
142
142
|
createPiModels,
|
|
143
143
|
modelRequestUrl,
|
|
@@ -25,3 +25,16 @@ export function maxExecutionLevel(
|
|
|
25
25
|
)
|
|
26
26
|
]!;
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
/** The most permissive level shared by an Agent and a Scheduled Task ceiling. */
|
|
30
|
+
export function minExecutionLevel(
|
|
31
|
+
left: ExecutionLevel,
|
|
32
|
+
right: ExecutionLevel,
|
|
33
|
+
): ExecutionLevel {
|
|
34
|
+
return EXECUTION_LEVELS[
|
|
35
|
+
Math.min(
|
|
36
|
+
EXECUTION_LEVELS.indexOf(left),
|
|
37
|
+
EXECUTION_LEVELS.indexOf(right),
|
|
38
|
+
)
|
|
39
|
+
]!;
|
|
40
|
+
}
|
package/src/lib/prompt.ts
CHANGED
|
@@ -17,9 +17,8 @@ export const PERSONA =
|
|
|
17
17
|
// Names the stable runtime environment.
|
|
18
18
|
export const RUNTIME =
|
|
19
19
|
"Runtime: this agent runs on Cloudflare Workers. When execute is present, its Code Mode Dynamic Worker is your " +
|
|
20
|
-
"instrument — code there runs with
|
|
21
|
-
"
|
|
22
|
-
"requests, parsing a payload, hitting several known endpoints, or computing over a file. Write plain " +
|
|
20
|
+
"instrument — code there runs with your workspace filesystem (state.*) and the tools.* methods listed in its own description. " +
|
|
21
|
+
"Use it for tool composition, parsing a payload, or computing over a file. Write plain " +
|
|
23
22
|
"JavaScript — the sandbox evaluates " +
|
|
24
23
|
"it directly, so TypeScript type annotations (`: number`, `as Type`) are a syntax error, and there " +
|
|
25
24
|
"is no Python interpreter or package manager to invoke. Use the JS/Workers equivalent of what you " +
|
|
@@ -58,8 +57,7 @@ export const TOOLS =
|
|
|
58
57
|
"use state.* for workspace file operations, tools.* for other host capabilities, and sequential calls for repeated or durable operations. " +
|
|
59
58
|
"Top-level-only Tools remain Direct even when called repeatedly. " +
|
|
60
59
|
"For web tasks, use web_search for web discovery, current facts, cited research, " +
|
|
61
|
-
"and public URL analysis
|
|
62
|
-
"API calls, or when web_search cannot retrieve the required content; do not use execute for ordinary web " +
|
|
60
|
+
"and public URL analysis; do not use execute for ordinary web " +
|
|
63
61
|
"searches. When execute is absent, use the actually exposed Direct Tools. When sandbox_* tools are present, use that isolated Linux environment for Python/Node, " +
|
|
64
62
|
"package managers, system commands, builds, tests and background processes; its filesystem is temporary, " +
|
|
65
63
|
"persistent inputs are copied in automatically on first use, /userspace is read-only, and only explicitly " +
|
package/src/models/index.ts
CHANGED
|
@@ -790,6 +790,7 @@ function configuredModel(
|
|
|
790
790
|
? {
|
|
791
791
|
compat: {
|
|
792
792
|
...anthropicMessagesCompat,
|
|
793
|
+
// OpenRouter rejects Anthropic's mid-conversation effort messages and block binding.
|
|
793
794
|
supportsMidConvoEffort: false,
|
|
794
795
|
supportsEagerToolInputStreaming: false,
|
|
795
796
|
supportsStrictTools:
|
|
@@ -716,6 +716,20 @@ export function migrateLegacyPiSession(
|
|
|
716
716
|
.map((row) => [row.message_id, row.submission_id] as const)
|
|
717
717
|
: [],
|
|
718
718
|
);
|
|
719
|
+
const submissionStatuses = new Map(
|
|
720
|
+
hasTable(sql, "pi_submissions")
|
|
721
|
+
? sql
|
|
722
|
+
.exec<{ submission_id: string; status: string }>(
|
|
723
|
+
"SELECT submission_id, status FROM pi_submissions",
|
|
724
|
+
)
|
|
725
|
+
.toArray()
|
|
726
|
+
.map((row) => [row.submission_id, row.status] as const)
|
|
727
|
+
: [],
|
|
728
|
+
);
|
|
729
|
+
const terminalSubmission = (submissionId: string): boolean =>
|
|
730
|
+
LEGACY_TERMINAL_SUBMISSION_STATUSES.has(
|
|
731
|
+
submissionStatuses.get(submissionId) ?? "",
|
|
732
|
+
);
|
|
719
733
|
const results = new Map<string, ToolResultMessage>();
|
|
720
734
|
for (const entry of converted.values()) {
|
|
721
735
|
if (entry.type !== "message" || entry.message.role !== "toolResult")
|
|
@@ -797,9 +811,6 @@ export function migrateLegacyPiSession(
|
|
|
797
811
|
const knownSubmissions = new Set(
|
|
798
812
|
submissions.map((row) => row.submission_id),
|
|
799
813
|
);
|
|
800
|
-
const submissionStatuses = new Map(
|
|
801
|
-
submissions.map((row) => [row.submission_id, row.status]),
|
|
802
|
-
);
|
|
803
814
|
for (const submission of submissions) {
|
|
804
815
|
if (submission.status !== "pending" || !submission.queued_input_json)
|
|
805
816
|
continue;
|
|
@@ -862,8 +873,12 @@ export function migrateLegacyPiSession(
|
|
|
862
873
|
.canonicalToolResults) {
|
|
863
874
|
const key = `${row.submission_id}:${result.toolCallId}`;
|
|
864
875
|
const previous = results.get(key);
|
|
865
|
-
if (previous
|
|
866
|
-
|
|
876
|
+
if (previous && !terminalSubmission(row.submission_id)) {
|
|
877
|
+
assertSameToolResult(previous, result);
|
|
878
|
+
}
|
|
879
|
+
if (!previous || !terminalSubmission(row.submission_id)) {
|
|
880
|
+
results.set(key, result);
|
|
881
|
+
}
|
|
867
882
|
}
|
|
868
883
|
}
|
|
869
884
|
}
|
|
@@ -875,8 +890,12 @@ export function migrateLegacyPiSession(
|
|
|
875
890
|
if (call.result) {
|
|
876
891
|
const key = `${submissionId}:${call.toolCallId}`;
|
|
877
892
|
const previous = results.get(key);
|
|
878
|
-
if (previous
|
|
879
|
-
|
|
893
|
+
if (previous && !terminalSubmission(submissionId)) {
|
|
894
|
+
assertSameToolResult(previous, call.result);
|
|
895
|
+
}
|
|
896
|
+
if (!previous || !terminalSubmission(submissionId)) {
|
|
897
|
+
results.set(key, call.result);
|
|
898
|
+
}
|
|
880
899
|
}
|
|
881
900
|
}
|
|
882
901
|
}
|
|
@@ -944,7 +963,9 @@ export function migrateLegacyPiSession(
|
|
|
944
963
|
const recorded = results.get(
|
|
945
964
|
`${row.submission_id}:${row.tool_call_id}`,
|
|
946
965
|
);
|
|
947
|
-
if (recorded
|
|
966
|
+
if (recorded && !terminalSubmission(row.submission_id)) {
|
|
967
|
+
assertSameToolResult(recorded, expected);
|
|
968
|
+
}
|
|
948
969
|
}
|
|
949
970
|
}
|
|
950
971
|
// The old table remains an inert backup. Failure rolls back DDL, data and the version together.
|
|
@@ -163,7 +163,7 @@ export const SPRINGBRAND_WORKER_WEBSITE_SKILL = {
|
|
|
163
163
|
"5. Call `get_browser_console_logs` for the home page and for every primary internal page. Check navigation responses, missing assets, exceptions, CSP or CORS failures, and client fetch failures.",
|
|
164
164
|
"6. Open the Website with the available browser evidence tools. For a multi-page Website, follow real links from the home page to every primary internal page and verify navigation back to the home page. Check at least the normal desktop viewport and one narrow viewport; capture and inspect a screenshot when visual appearance matters.",
|
|
165
165
|
"7. Fix every failure, redeploy, and repeat the same checks. A clean home page does not prove a multi-page Website works.",
|
|
166
|
-
"8. After browser verification succeeds, call `save_creation` exactly once with the existing entry HTML Working Copy path. For the recommended layout, that is `/creations/<website-name>/public/index.html`.",
|
|
166
|
+
"8. After browser verification succeeds, call `save_creation` exactly once with a user-visible title and the existing entry HTML Working Copy path. For the recommended layout, that path is `/creations/<website-name>/public/index.html`.",
|
|
167
167
|
"9. Do not call the Website complete until `save_creation` returns an `artifactId`. Do not save referenced assets as separate Creations.",
|
|
168
168
|
"",
|
|
169
169
|
"## Publication contract",
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
} from "./lifecycle";
|
|
15
15
|
import { isTerminalSubmissionStatus, submissionAbortReason, type StoredSubmission, type SubmissionOrigin, type SubmissionRepository } from "./repository";
|
|
16
16
|
import type { RuntimeUnattendedExecutionGrant } from "./contracts";
|
|
17
|
+
import type { ExecutionLevel } from "../lib/execution-level";
|
|
17
18
|
|
|
18
19
|
// Pending records retain identity indefinitely; only recent attempts reserve capacity.
|
|
19
20
|
const ADMISSION_ATTEMPT_WINDOW_MS = 60_000;
|
|
@@ -26,6 +27,8 @@ export interface SubmitMessageOptions {
|
|
|
26
27
|
regenerate?: boolean;
|
|
27
28
|
/** `scheduled` marks a Run injection that locks ordinary input until it ends. */
|
|
28
29
|
origin?: SubmissionOrigin;
|
|
30
|
+
/** Maximum execution level allowed by the Schedule Definition. */
|
|
31
|
+
scheduledMaxExecutionLevel?: ExecutionLevel;
|
|
29
32
|
/** Trusted Host grant; accepted only for a scheduled Submission. */
|
|
30
33
|
unattendedExecutionGrant?: RuntimeUnattendedExecutionGrant;
|
|
31
34
|
/** Internal transfer of a durable accepted steer; never a public message option. */
|
|
@@ -188,6 +191,7 @@ export class SubmissionAdmission {
|
|
|
188
191
|
: null,
|
|
189
192
|
runId,
|
|
190
193
|
origin: options.origin,
|
|
194
|
+
scheduledMaxExecutionLevel: options.scheduledMaxExecutionLevel,
|
|
191
195
|
unattendedExecutionGrant: options.unattendedExecutionGrant,
|
|
192
196
|
});
|
|
193
197
|
const admitted = this.options.submissions.find(runId)!;
|
|
@@ -2,7 +2,7 @@ import type { UIMessage } from "ai";
|
|
|
2
2
|
import type { PiCanonicalUserInput } from "../conversation/message/contract";
|
|
3
3
|
import type { RuntimeTelemetryCoordinator } from "../telemetry/coordinator";
|
|
4
4
|
import type { RuntimeTurnEvents } from "../telemetry/turn-events";
|
|
5
|
-
import type { HarnessHumanDecisions } from "../tools/human-decisions";
|
|
5
|
+
import type { HarnessHumanDecisions } from "../tools/runtime/human-decisions";
|
|
6
6
|
import type { SubmitMessageOptions } from "./admission";
|
|
7
7
|
import {
|
|
8
8
|
projectSubmissionReceipt,
|
|
@@ -4,7 +4,7 @@ import type { ConversationHistory } from "../conversation/history";
|
|
|
4
4
|
import type { MessageUiRepository } from "../conversation/repository";
|
|
5
5
|
import type { RuntimeTelemetryCoordinator } from "../telemetry/coordinator";
|
|
6
6
|
import type { RuntimeTurnEvents } from "../telemetry/turn-events";
|
|
7
|
-
import type { HarnessHumanDecisions } from "../tools/human-decisions";
|
|
7
|
+
import type { HarnessHumanDecisions } from "../tools/runtime/human-decisions";
|
|
8
8
|
import { USER_STOP_REASON } from "./contracts";
|
|
9
9
|
import type { SubmissionOutcome } from "./lifecycle";
|
|
10
10
|
import { isTerminalSubmissionStatus, type StoredSubmission, type SubmissionRepository } from "./repository";
|