@treeseed/agent 0.8.5
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/Dockerfile +7 -0
- package/README.md +198 -0
- package/dist/agent-runtime.d.ts +17 -0
- package/dist/agent-runtime.js +117 -0
- package/dist/agents/adapters/execution.d.ts +41 -0
- package/dist/agents/adapters/execution.js +73 -0
- package/dist/agents/adapters/mutations.d.ts +22 -0
- package/dist/agents/adapters/mutations.js +30 -0
- package/dist/agents/adapters/notification.d.ts +26 -0
- package/dist/agents/adapters/notification.js +46 -0
- package/dist/agents/adapters/repository.d.ts +28 -0
- package/dist/agents/adapters/repository.js +61 -0
- package/dist/agents/adapters/research.d.ts +26 -0
- package/dist/agents/adapters/research.js +59 -0
- package/dist/agents/adapters/verification.d.ts +36 -0
- package/dist/agents/adapters/verification.js +62 -0
- package/dist/agents/cli-tools.d.ts +1 -0
- package/dist/agents/cli-tools.js +5 -0
- package/dist/agents/cli.d.ts +15 -0
- package/dist/agents/cli.js +109 -0
- package/dist/agents/contracts/messages.d.ts +88 -0
- package/dist/agents/contracts/messages.js +138 -0
- package/dist/agents/contracts/run.d.ts +21 -0
- package/dist/agents/contracts/run.js +0 -0
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/index.js +5 -0
- package/dist/agents/kernel/agent-kernel.d.ts +63 -0
- package/dist/agents/kernel/agent-kernel.js +291 -0
- package/dist/agents/kernel/trigger-resolver.d.ts +19 -0
- package/dist/agents/kernel/trigger-resolver.js +157 -0
- package/dist/agents/registry-helper.d.ts +4 -0
- package/dist/agents/registry-helper.js +14 -0
- package/dist/agents/registry.d.ts +6 -0
- package/dist/agents/registry.js +98 -0
- package/dist/agents/runtime-types.d.ts +118 -0
- package/dist/agents/runtime-types.js +0 -0
- package/dist/agents/spec-loader.d.ts +18 -0
- package/dist/agents/spec-loader.js +54 -0
- package/dist/agents/spec-normalizer.d.ts +2 -0
- package/dist/agents/spec-normalizer.js +327 -0
- package/dist/agents/spec-types.d.ts +64 -0
- package/dist/agents/spec-types.js +0 -0
- package/dist/agents/testing/agents-smoke.d.ts +1 -0
- package/dist/agents/testing/agents-smoke.js +32 -0
- package/dist/agents/testing/e2e-harness.d.ts +44 -0
- package/dist/agents/testing/e2e-harness.js +503 -0
- package/dist/api/agent-routes.d.ts +13 -0
- package/dist/api/agent-routes.js +327 -0
- package/dist/api/app.d.ts +8 -0
- package/dist/api/app.js +444 -0
- package/dist/api/auth/d1-database.d.ts +3 -0
- package/dist/api/auth/d1-database.js +20 -0
- package/dist/api/auth/d1-provider.d.ts +79 -0
- package/dist/api/auth/d1-provider.js +92 -0
- package/dist/api/auth/d1-store.d.ts +114 -0
- package/dist/api/auth/d1-store.js +895 -0
- package/dist/api/auth/memory-provider.d.ts +77 -0
- package/dist/api/auth/memory-provider.js +249 -0
- package/dist/api/auth/rbac.d.ts +22 -0
- package/dist/api/auth/rbac.js +162 -0
- package/dist/api/auth/tokens.d.ts +18 -0
- package/dist/api/auth/tokens.js +56 -0
- package/dist/api/capabilities.d.ts +9 -0
- package/dist/api/capabilities.js +33 -0
- package/dist/api/config.d.ts +2 -0
- package/dist/api/config.js +77 -0
- package/dist/api/http.d.ts +28 -0
- package/dist/api/http.js +51 -0
- package/dist/api/index.d.ts +9 -0
- package/dist/api/index.js +20 -0
- package/dist/api/operations-routes.d.ts +11 -0
- package/dist/api/operations-routes.js +87 -0
- package/dist/api/operations.d.ts +3 -0
- package/dist/api/operations.js +26 -0
- package/dist/api/project-routes.d.ts +8 -0
- package/dist/api/project-routes.js +585 -0
- package/dist/api/providers.d.ts +2 -0
- package/dist/api/providers.js +62 -0
- package/dist/api/railway.d.ts +51 -0
- package/dist/api/railway.js +71 -0
- package/dist/api/sdk-dispatch.d.ts +5 -0
- package/dist/api/sdk-dispatch.js +13 -0
- package/dist/api/sdk-routes.d.ts +11 -0
- package/dist/api/sdk-routes.js +29 -0
- package/dist/api/server.d.ts +2 -0
- package/dist/api/server.js +10 -0
- package/dist/api/templates.d.ts +3 -0
- package/dist/api/templates.js +31 -0
- package/dist/api/types.d.ts +237 -0
- package/dist/api/types.js +0 -0
- package/dist/env.yaml +957 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +41 -0
- package/dist/scripts/assert-release-tag-version.d.ts +1 -0
- package/dist/scripts/assert-release-tag-version.js +20 -0
- package/dist/scripts/build-dist.d.ts +1 -0
- package/dist/scripts/build-dist.js +106 -0
- package/dist/scripts/package-tools.d.ts +1 -0
- package/dist/scripts/package-tools.js +7 -0
- package/dist/scripts/publish-package.d.ts +1 -0
- package/dist/scripts/publish-package.js +24 -0
- package/dist/scripts/release-verify.d.ts +1 -0
- package/dist/scripts/release-verify.js +152 -0
- package/dist/scripts/test-smoke.d.ts +1 -0
- package/dist/scripts/test-smoke.js +23 -0
- package/dist/scripts/treeseed-agent-api.d.ts +2 -0
- package/dist/scripts/treeseed-agent-api.js +25 -0
- package/dist/scripts/treeseed-agent-service.d.ts +2 -0
- package/dist/scripts/treeseed-agent-service.js +36 -0
- package/dist/scripts/treeseed-agents.d.ts +2 -0
- package/dist/scripts/treeseed-agents.js +13 -0
- package/dist/services/agents.d.ts +17 -0
- package/dist/services/agents.js +48 -0
- package/dist/services/common.d.ts +66 -0
- package/dist/services/common.js +212 -0
- package/dist/services/index.d.ts +6 -0
- package/dist/services/index.js +19 -0
- package/dist/services/manager.d.ts +333 -0
- package/dist/services/manager.js +1368 -0
- package/dist/services/remote-runner.d.ts +30 -0
- package/dist/services/remote-runner.js +230 -0
- package/dist/services/workday-content.d.ts +53 -0
- package/dist/services/workday-content.js +190 -0
- package/dist/services/workday-manager.d.ts +391 -0
- package/dist/services/workday-manager.js +163 -0
- package/dist/services/workday-report.d.ts +238 -0
- package/dist/services/workday-report.js +17 -0
- package/dist/services/workday-start.d.ts +238 -0
- package/dist/services/workday-start.js +17 -0
- package/dist/services/worker-capacity.d.ts +58 -0
- package/dist/services/worker-capacity.js +208 -0
- package/dist/services/worker-pool-scaler.d.ts +27 -0
- package/dist/services/worker-pool-scaler.js +127 -0
- package/dist/services/worker.d.ts +19 -0
- package/dist/services/worker.js +436 -0
- package/dist/templates/github/deploy-processing.workflow.yml +119 -0
- package/package.json +136 -0
- package/templates/github/deploy-processing.workflow.yml +119 -0
package/Dockerfile
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# `@treeseed/agent`
|
|
2
|
+
|
|
3
|
+
Treeseed agent service runtime package.
|
|
4
|
+
|
|
5
|
+
This package publishes the `treeseed-agents` CLI, the shared runtime exports for TreeSeed agents, and the Node service entrypoints used by the unified agent-hosting system.
|
|
6
|
+
|
|
7
|
+
## What It Provides
|
|
8
|
+
|
|
9
|
+
- the existing `treeseed-agents` CLI for local runtime inspection and execution
|
|
10
|
+
- `manager` for work-day orchestration, graph ownership, and context assembly
|
|
11
|
+
- `worker` for bounded task execution against Cloudflare Queue deliveries
|
|
12
|
+
- `workday-start` and `workday-report` for cron-friendly kickoff and reporting
|
|
13
|
+
- helper scripts for running a local manager against a deployed Cloudflare site and gateway
|
|
14
|
+
|
|
15
|
+
## Deployment Shapes
|
|
16
|
+
|
|
17
|
+
This package supports three useful shapes:
|
|
18
|
+
|
|
19
|
+
1. Fully local
|
|
20
|
+
2. Cloudflare site + local manager on your laptop
|
|
21
|
+
3. Cloudflare control plane + Railway manager/worker services
|
|
22
|
+
|
|
23
|
+
The hybrid laptop-manager flow is explicitly supported. The manager is just a Node process and can talk to a deployed Cloudflare gateway and queue as long as the right env vars are set.
|
|
24
|
+
|
|
25
|
+
## Requirements
|
|
26
|
+
|
|
27
|
+
- Node `>=22`
|
|
28
|
+
- npm
|
|
29
|
+
- a Treeseed tenant repository for runtime commands such as `doctor` and `start`
|
|
30
|
+
|
|
31
|
+
## Install
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install @treeseed/agent @treeseed/sdk
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Build And Test
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm install
|
|
41
|
+
npm run build
|
|
42
|
+
npm test
|
|
43
|
+
npm run release:verify
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`npm test` runs the package smoke test. `npm run release:verify` rebuilds the package, runs the smoke test, and verifies that the packed tarball installs cleanly with the published `treeseed-agents` binary.
|
|
47
|
+
|
|
48
|
+
`npm test` currently validates the legacy smoke path. For the new hosting stack, the minimum package-local verification is:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm run build
|
|
52
|
+
npm run dev:manager
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
and, when configured:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm run dev:worker
|
|
59
|
+
npm run dev:workday-start
|
|
60
|
+
npm run dev:workday-report
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## CLI
|
|
64
|
+
|
|
65
|
+
Run the CLI from a Treeseed tenant repository root, or set `TREESEED_TENANT_ROOT` to point at one.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
treeseed-agents doctor
|
|
69
|
+
treeseed-agents run-agent planner-agent
|
|
70
|
+
treeseed-agents start
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Available commands:
|
|
74
|
+
|
|
75
|
+
- `doctor`
|
|
76
|
+
- `run-agent <slug>`
|
|
77
|
+
- `drain-messages`
|
|
78
|
+
- `release-leases`
|
|
79
|
+
- `replay-message <id>`
|
|
80
|
+
- `start`
|
|
81
|
+
|
|
82
|
+
## Service Commands
|
|
83
|
+
|
|
84
|
+
Development entrypoints:
|
|
85
|
+
|
|
86
|
+
- `npm run dev:manager`
|
|
87
|
+
- `npm run dev:worker`
|
|
88
|
+
- `npm run dev:workday-start`
|
|
89
|
+
- `npm run dev:workday-report`
|
|
90
|
+
|
|
91
|
+
Built entrypoints:
|
|
92
|
+
|
|
93
|
+
- `npm run start:manager`
|
|
94
|
+
- `npm run start:worker`
|
|
95
|
+
- `npm run start:workday-start`
|
|
96
|
+
- `npm run start:workday-report`
|
|
97
|
+
|
|
98
|
+
Hybrid convenience entrypoint:
|
|
99
|
+
|
|
100
|
+
- `npm run start:local-manager-cloudflare`
|
|
101
|
+
|
|
102
|
+
## Local Manager With Cloudflare
|
|
103
|
+
|
|
104
|
+
Use this when:
|
|
105
|
+
|
|
106
|
+
- your site is deployed on Cloudflare
|
|
107
|
+
- your gateway Worker is deployed on Cloudflare
|
|
108
|
+
- you want the agent manager running on your laptop instead of Railway
|
|
109
|
+
|
|
110
|
+
Setup:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
cp .env.local-manager-cloudflare.example .env.local-manager-cloudflare
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Required values:
|
|
117
|
+
|
|
118
|
+
- `TREESEED_AGENT_REPO_ROOT`
|
|
119
|
+
- `TREESEED_GATEWAY_BASE_URL`
|
|
120
|
+
- `TREESEED_GATEWAY_BEARER_TOKEN`
|
|
121
|
+
- `CLOUDFLARE_ACCOUNT_ID`
|
|
122
|
+
- `TREESEED_QUEUE_ID`
|
|
123
|
+
|
|
124
|
+
If you also want a local worker, set:
|
|
125
|
+
|
|
126
|
+
- `TREESEED_QUEUE_PULL_TOKEN`
|
|
127
|
+
|
|
128
|
+
Start the manager:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npm run start:local-manager-cloudflare
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Start a local worker in another shell:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
set -a; source ./.env.local-manager-cloudflare; set +a
|
|
138
|
+
npm run dev:worker
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Kick off the work day:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
set -a; source ./.env.local-manager-cloudflare; set +a
|
|
145
|
+
npm run dev:workday-start
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Generate the report:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
set -a; source ./.env.local-manager-cloudflare; set +a
|
|
152
|
+
npm run dev:workday-report
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Environment
|
|
156
|
+
|
|
157
|
+
Common runtime variables:
|
|
158
|
+
|
|
159
|
+
- `TREESEED_AGENT_REPO_ROOT`
|
|
160
|
+
- `TREESEED_AGENT_D1_DATABASE`
|
|
161
|
+
- `TREESEED_AGENT_D1_PERSIST_TO`
|
|
162
|
+
- `TREESEED_PROJECT_ID`
|
|
163
|
+
- `TREESEED_WORKDAY_CAPACITY_BUDGET`
|
|
164
|
+
- `TREESEED_GATEWAY_BASE_URL`
|
|
165
|
+
- `TREESEED_GATEWAY_BEARER_TOKEN`
|
|
166
|
+
- `TREESEED_MANAGER_BASE_URL`
|
|
167
|
+
- `TREESEED_WORKER_ID`
|
|
168
|
+
- `TREESEED_QUEUE_BATCH_SIZE`
|
|
169
|
+
- `TREESEED_QUEUE_VISIBILITY_TIMEOUT_MS`
|
|
170
|
+
- `TREESEED_TASK_LEASE_SECONDS`
|
|
171
|
+
- `TREESEED_WORKER_POLL_INTERVAL_MS`
|
|
172
|
+
- `CLOUDFLARE_ACCOUNT_ID`
|
|
173
|
+
- `TREESEED_QUEUE_ID`
|
|
174
|
+
- `TREESEED_QUEUE_PULL_TOKEN`
|
|
175
|
+
|
|
176
|
+
## Package Scripts
|
|
177
|
+
|
|
178
|
+
- `npm run setup`: install dependencies with `npm install`
|
|
179
|
+
- `npm run setup:ci`: install dependencies with `npm ci`
|
|
180
|
+
- `npm run build`: build the distributable package
|
|
181
|
+
- `npm run dev:manager`: run the manager directly from source
|
|
182
|
+
- `npm run dev:worker`: run the worker directly from source
|
|
183
|
+
- `npm run dev:workday-start`: run the cron-style start entrypoint directly from source
|
|
184
|
+
- `npm run dev:workday-report`: run the cron-style report entrypoint directly from source
|
|
185
|
+
- `npm run start:manager`: run the built manager
|
|
186
|
+
- `npm run start:worker`: run the built worker
|
|
187
|
+
- `npm run start:workday-start`: run the built workday-start entrypoint
|
|
188
|
+
- `npm run start:workday-report`: run the built workday-report entrypoint
|
|
189
|
+
- `npm run start:local-manager-cloudflare`: load the local-manager env file and start the built manager
|
|
190
|
+
- `npm test`: run the smoke test
|
|
191
|
+
- `npm run release:verify`: verify build, smoke test, and packed-install behavior
|
|
192
|
+
- `npm run release:check-tag -- <tag>`: validate plain semver tags like `0.1.1` against `package.json`
|
|
193
|
+
- `npm run release:publish`: publish to npm
|
|
194
|
+
|
|
195
|
+
## GitHub Actions
|
|
196
|
+
|
|
197
|
+
- `.github/workflows/ci.yml` runs `npm ci`, `npm run build`, `npm test`, and `npm run release:verify` on pushes and pull requests.
|
|
198
|
+
- `.github/workflows/publish.yml` runs the same verification steps before publishing on `*.*.*` version tags or manual dispatch.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AgentExecutionAdapter, AgentHandler, AgentMutationAdapter, AgentNotificationAdapter, AgentRepositoryInspectionAdapter, AgentResearchAdapter, AgentVerificationAdapter } from './agents/runtime-types.ts';
|
|
2
|
+
export declare function resolveAgentRuntimeProviders(repoRoot: string, selections: {
|
|
3
|
+
execution: string;
|
|
4
|
+
mutation: string;
|
|
5
|
+
repository: string;
|
|
6
|
+
verification: string;
|
|
7
|
+
notification: string;
|
|
8
|
+
research: string;
|
|
9
|
+
}): {
|
|
10
|
+
execution: AgentExecutionAdapter;
|
|
11
|
+
mutations: AgentMutationAdapter;
|
|
12
|
+
repository: AgentRepositoryInspectionAdapter;
|
|
13
|
+
verification: AgentVerificationAdapter;
|
|
14
|
+
notifications: AgentNotificationAdapter;
|
|
15
|
+
research: AgentResearchAdapter;
|
|
16
|
+
handlers: Map<string, AgentHandler<unknown, unknown>>;
|
|
17
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { loadTreeseedPluginRuntime } from "@treeseed/sdk/platform/plugins";
|
|
2
|
+
import {
|
|
3
|
+
CopilotExecutionAdapter,
|
|
4
|
+
ManualExecutionAdapter,
|
|
5
|
+
StubExecutionAdapter
|
|
6
|
+
} from "./agents/adapters/execution.js";
|
|
7
|
+
import { LocalBranchMutationAdapter } from "./agents/adapters/mutations.js";
|
|
8
|
+
import { SdkMessageNotificationAdapter, StubNotificationAdapter } from "./agents/adapters/notification.js";
|
|
9
|
+
import { GitRepositoryInspectionAdapter, StubRepositoryInspectionAdapter } from "./agents/adapters/repository.js";
|
|
10
|
+
import { ProjectGraphResearchAdapter, StubResearchAdapter } from "./agents/adapters/research.js";
|
|
11
|
+
import { LocalVerificationAdapter, StubVerificationAdapter } from "./agents/adapters/verification.js";
|
|
12
|
+
let cachedAgentRuntime = null;
|
|
13
|
+
function readPluginRecord(pluginEntry, key) {
|
|
14
|
+
const value = pluginEntry.plugin[key];
|
|
15
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
16
|
+
}
|
|
17
|
+
function assertUniqueProvider(registry, id, owner) {
|
|
18
|
+
if (registry.has(id)) {
|
|
19
|
+
throw new Error(`Treeseed plugin runtime found duplicate provider "${id}" from ${owner}.`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function collectAgentHandlersFromPlugin(pluginEntry, registry) {
|
|
23
|
+
const contributedHandlers = readPluginRecord(pluginEntry, "agentHandlers");
|
|
24
|
+
for (const [id, handler] of Object.entries(contributedHandlers)) {
|
|
25
|
+
assertUniqueProvider(registry, id, pluginEntry.package);
|
|
26
|
+
registry.set(id, handler);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function buildAgentRuntime() {
|
|
30
|
+
const runtime = loadTreeseedPluginRuntime();
|
|
31
|
+
const execution = /* @__PURE__ */ new Map([
|
|
32
|
+
["stub", () => new StubExecutionAdapter()],
|
|
33
|
+
["manual", () => new ManualExecutionAdapter()],
|
|
34
|
+
["copilot", () => new CopilotExecutionAdapter()]
|
|
35
|
+
]);
|
|
36
|
+
const mutation = /* @__PURE__ */ new Map([
|
|
37
|
+
["local_branch", (repoRoot) => new LocalBranchMutationAdapter(repoRoot)]
|
|
38
|
+
]);
|
|
39
|
+
const repository = /* @__PURE__ */ new Map([
|
|
40
|
+
["stub", () => new StubRepositoryInspectionAdapter()],
|
|
41
|
+
["git", () => new GitRepositoryInspectionAdapter()]
|
|
42
|
+
]);
|
|
43
|
+
const verification = /* @__PURE__ */ new Map([
|
|
44
|
+
["stub", () => new StubVerificationAdapter()],
|
|
45
|
+
["local", () => new LocalVerificationAdapter()]
|
|
46
|
+
]);
|
|
47
|
+
const notification = /* @__PURE__ */ new Map([
|
|
48
|
+
["stub", () => new StubNotificationAdapter()],
|
|
49
|
+
["sdk_message", () => new SdkMessageNotificationAdapter()]
|
|
50
|
+
]);
|
|
51
|
+
const research = /* @__PURE__ */ new Map([
|
|
52
|
+
["stub", () => new StubResearchAdapter()],
|
|
53
|
+
["project_graph", () => new ProjectGraphResearchAdapter()]
|
|
54
|
+
]);
|
|
55
|
+
const handlers = /* @__PURE__ */ new Map();
|
|
56
|
+
for (const pluginEntry of runtime.plugins) {
|
|
57
|
+
const agentProviders = readPluginRecord(pluginEntry, "agentProviders");
|
|
58
|
+
for (const [id, factory] of Object.entries(agentProviders.execution ?? {})) {
|
|
59
|
+
assertUniqueProvider(execution, id, pluginEntry.package);
|
|
60
|
+
execution.set(id, factory);
|
|
61
|
+
}
|
|
62
|
+
for (const [id, factory] of Object.entries(agentProviders.mutation ?? {})) {
|
|
63
|
+
assertUniqueProvider(mutation, id, pluginEntry.package);
|
|
64
|
+
mutation.set(id, factory);
|
|
65
|
+
}
|
|
66
|
+
for (const [id, factory] of Object.entries(agentProviders.repository ?? {})) {
|
|
67
|
+
assertUniqueProvider(repository, id, pluginEntry.package);
|
|
68
|
+
repository.set(id, factory);
|
|
69
|
+
}
|
|
70
|
+
for (const [id, factory] of Object.entries(agentProviders.verification ?? {})) {
|
|
71
|
+
assertUniqueProvider(verification, id, pluginEntry.package);
|
|
72
|
+
verification.set(id, factory);
|
|
73
|
+
}
|
|
74
|
+
for (const [id, factory] of Object.entries(agentProviders.notification ?? {})) {
|
|
75
|
+
assertUniqueProvider(notification, id, pluginEntry.package);
|
|
76
|
+
notification.set(id, factory);
|
|
77
|
+
}
|
|
78
|
+
for (const [id, factory] of Object.entries(agentProviders.research ?? {})) {
|
|
79
|
+
assertUniqueProvider(research, id, pluginEntry.package);
|
|
80
|
+
research.set(id, factory);
|
|
81
|
+
}
|
|
82
|
+
collectAgentHandlersFromPlugin(pluginEntry, handlers);
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
providers: { execution, mutation, repository, verification, notification, research },
|
|
86
|
+
handlers
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function resolveAgentRuntimeProviders(repoRoot, selections) {
|
|
90
|
+
if (!cachedAgentRuntime) {
|
|
91
|
+
cachedAgentRuntime = buildAgentRuntime();
|
|
92
|
+
}
|
|
93
|
+
const executionFactory = cachedAgentRuntime.providers.execution.get(selections.execution);
|
|
94
|
+
const mutationFactory = cachedAgentRuntime.providers.mutation.get(selections.mutation);
|
|
95
|
+
const repositoryFactory = cachedAgentRuntime.providers.repository.get(selections.repository);
|
|
96
|
+
const verificationFactory = cachedAgentRuntime.providers.verification.get(selections.verification);
|
|
97
|
+
const notificationFactory = cachedAgentRuntime.providers.notification.get(selections.notification);
|
|
98
|
+
const researchFactory = cachedAgentRuntime.providers.research.get(selections.research);
|
|
99
|
+
if (!executionFactory) throw new Error(`Treeseed agent execution provider "${selections.execution}" is not registered.`);
|
|
100
|
+
if (!mutationFactory) throw new Error(`Treeseed agent mutation provider "${selections.mutation}" is not registered.`);
|
|
101
|
+
if (!repositoryFactory) throw new Error(`Treeseed agent repository provider "${selections.repository}" is not registered.`);
|
|
102
|
+
if (!verificationFactory) throw new Error(`Treeseed agent verification provider "${selections.verification}" is not registered.`);
|
|
103
|
+
if (!notificationFactory) throw new Error(`Treeseed agent notification provider "${selections.notification}" is not registered.`);
|
|
104
|
+
if (!researchFactory) throw new Error(`Treeseed agent research provider "${selections.research}" is not registered.`);
|
|
105
|
+
return {
|
|
106
|
+
execution: executionFactory(),
|
|
107
|
+
mutations: mutationFactory(repoRoot),
|
|
108
|
+
repository: repositoryFactory(),
|
|
109
|
+
verification: verificationFactory(),
|
|
110
|
+
notifications: notificationFactory(),
|
|
111
|
+
research: researchFactory(),
|
|
112
|
+
handlers: cachedAgentRuntime.handlers
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
export {
|
|
116
|
+
resolveAgentRuntimeProviders
|
|
117
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { AgentExecutionAdapter } from '../runtime-types.ts';
|
|
2
|
+
export declare class StubExecutionAdapter implements AgentExecutionAdapter {
|
|
3
|
+
runTask(input: {
|
|
4
|
+
prompt: string;
|
|
5
|
+
runId: string;
|
|
6
|
+
}): Promise<{
|
|
7
|
+
status: "completed";
|
|
8
|
+
summary: string;
|
|
9
|
+
stdout: string;
|
|
10
|
+
stderr: string;
|
|
11
|
+
}>;
|
|
12
|
+
}
|
|
13
|
+
export declare class CopilotExecutionAdapter implements AgentExecutionAdapter {
|
|
14
|
+
runTask(input: {
|
|
15
|
+
agent: {
|
|
16
|
+
cli?: {
|
|
17
|
+
model?: string;
|
|
18
|
+
allowTools?: string[];
|
|
19
|
+
additionalArgs?: string[];
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
prompt: string;
|
|
23
|
+
}): Promise<{
|
|
24
|
+
stderr: string;
|
|
25
|
+
status: "completed" | "failed";
|
|
26
|
+
summary: string;
|
|
27
|
+
stdout: string;
|
|
28
|
+
}>;
|
|
29
|
+
}
|
|
30
|
+
export declare class ManualExecutionAdapter implements AgentExecutionAdapter {
|
|
31
|
+
runTask(input: {
|
|
32
|
+
prompt: string;
|
|
33
|
+
runId: string;
|
|
34
|
+
}): Promise<{
|
|
35
|
+
status: "completed";
|
|
36
|
+
summary: string;
|
|
37
|
+
stdout: string;
|
|
38
|
+
stderr: string;
|
|
39
|
+
}>;
|
|
40
|
+
}
|
|
41
|
+
export declare function createExecutionAdapter(): StubExecutionAdapter | CopilotExecutionAdapter | ManualExecutionAdapter;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { normalizeAgentCliOptions } from "../cli-tools.js";
|
|
2
|
+
import { getTreeseedAgentProviderSelections } from "@treeseed/sdk/platform/deploy-runtime";
|
|
3
|
+
import { runTreeseedCopilotTask } from "@treeseed/sdk/copilot";
|
|
4
|
+
class StubExecutionAdapter {
|
|
5
|
+
async runTask(input) {
|
|
6
|
+
return {
|
|
7
|
+
status: "completed",
|
|
8
|
+
summary: `Stubbed Copilot execution for ${input.runId}.`,
|
|
9
|
+
stdout: [
|
|
10
|
+
"# Planned Task",
|
|
11
|
+
"",
|
|
12
|
+
"1. Inspect the requested architecture context.",
|
|
13
|
+
"2. Produce a safe local change artifact.",
|
|
14
|
+
"3. Summarize the implementation intent.",
|
|
15
|
+
"",
|
|
16
|
+
`Prompt digest: ${input.prompt.slice(0, 240)}`
|
|
17
|
+
].join("\n"),
|
|
18
|
+
stderr: ""
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
class CopilotExecutionAdapter {
|
|
23
|
+
async runTask(input) {
|
|
24
|
+
const cli = normalizeAgentCliOptions(input.agent.cli);
|
|
25
|
+
const result = await runTreeseedCopilotTask({
|
|
26
|
+
prompt: input.prompt,
|
|
27
|
+
cwd: process.cwd(),
|
|
28
|
+
model: cli.model,
|
|
29
|
+
allowTools: cli.allowTools,
|
|
30
|
+
env: process.env
|
|
31
|
+
});
|
|
32
|
+
const ignoredArgs = cli.additionalArgs?.length ? `Ignored Copilot CLI-only arguments because Treeseed uses @github/copilot-sdk internally: ${cli.additionalArgs.join(" ")}` : "";
|
|
33
|
+
return {
|
|
34
|
+
...result,
|
|
35
|
+
stderr: [result.stderr, ignoredArgs].filter(Boolean).join("\n")
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
class ManualExecutionAdapter {
|
|
40
|
+
async runTask(input) {
|
|
41
|
+
return {
|
|
42
|
+
status: "completed",
|
|
43
|
+
summary: `Manual execution mode is enabled for ${input.runId}.`,
|
|
44
|
+
stdout: [
|
|
45
|
+
"# Manual Execution Required",
|
|
46
|
+
"",
|
|
47
|
+
"This agent run is configured for manual execution.",
|
|
48
|
+
"Review the prompt below and complete the work outside the automated adapter.",
|
|
49
|
+
"",
|
|
50
|
+
input.prompt
|
|
51
|
+
].join("\n"),
|
|
52
|
+
stderr: ""
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function createExecutionAdapter() {
|
|
57
|
+
const configuredMode = String(
|
|
58
|
+
process.env.TREESEED_AGENT_EXECUTION_PROVIDER ?? getTreeseedAgentProviderSelections().execution
|
|
59
|
+
).toLowerCase();
|
|
60
|
+
if (configuredMode === "manual") {
|
|
61
|
+
return new ManualExecutionAdapter();
|
|
62
|
+
}
|
|
63
|
+
if (configuredMode !== "copilot") {
|
|
64
|
+
return new StubExecutionAdapter();
|
|
65
|
+
}
|
|
66
|
+
return new CopilotExecutionAdapter();
|
|
67
|
+
}
|
|
68
|
+
export {
|
|
69
|
+
CopilotExecutionAdapter,
|
|
70
|
+
ManualExecutionAdapter,
|
|
71
|
+
StubExecutionAdapter,
|
|
72
|
+
createExecutionAdapter
|
|
73
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { AgentMutationAdapter } from '../runtime-types.ts';
|
|
2
|
+
export declare class LocalBranchMutationAdapter implements AgentMutationAdapter {
|
|
3
|
+
private readonly git;
|
|
4
|
+
constructor(repoRoot: string);
|
|
5
|
+
writeArtifact(input: {
|
|
6
|
+
runId: string;
|
|
7
|
+
agent: {
|
|
8
|
+
execution: {
|
|
9
|
+
branchPrefix: string;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
relativePath: string;
|
|
13
|
+
content: string;
|
|
14
|
+
commitMessage: string;
|
|
15
|
+
}): Promise<{
|
|
16
|
+
branchName: string;
|
|
17
|
+
commitMessage: string;
|
|
18
|
+
worktreePath: string;
|
|
19
|
+
commitSha: string | null;
|
|
20
|
+
changedPaths: string[];
|
|
21
|
+
}>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { GitRuntime } from "@treeseed/sdk/git-runtime";
|
|
4
|
+
class LocalBranchMutationAdapter {
|
|
5
|
+
git;
|
|
6
|
+
constructor(repoRoot) {
|
|
7
|
+
this.git = new GitRuntime(
|
|
8
|
+
repoRoot,
|
|
9
|
+
process.env.TREESEED_AGENT_DISABLE_GIT === "true"
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
async writeArtifact(input) {
|
|
13
|
+
const branchName = `${input.agent.execution.branchPrefix}/${input.runId}`;
|
|
14
|
+
const worktreePath = await this.git.ensureWorktree(branchName);
|
|
15
|
+
const filePath = path.join(worktreePath, input.relativePath);
|
|
16
|
+
await mkdir(path.dirname(filePath), { recursive: true });
|
|
17
|
+
await writeFile(filePath, input.content, "utf8");
|
|
18
|
+
const git = await this.git.commitFileChange(filePath, branchName, input.commitMessage);
|
|
19
|
+
return {
|
|
20
|
+
branchName: git.branchName,
|
|
21
|
+
commitMessage: git.commitMessage,
|
|
22
|
+
worktreePath: git.worktreePath,
|
|
23
|
+
commitSha: git.commitSha,
|
|
24
|
+
changedPaths: git.changedPaths
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
LocalBranchMutationAdapter
|
|
30
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AgentNotificationAdapter } from '../runtime-types.ts';
|
|
2
|
+
export declare class StubNotificationAdapter implements AgentNotificationAdapter {
|
|
3
|
+
deliver(input: {
|
|
4
|
+
recipients: string[];
|
|
5
|
+
}): Promise<{
|
|
6
|
+
status: "waiting" | "completed";
|
|
7
|
+
summary: string;
|
|
8
|
+
deliveredCount: number;
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
11
|
+
export declare class SdkMessageNotificationAdapter implements AgentNotificationAdapter {
|
|
12
|
+
deliver(input: {
|
|
13
|
+
agent: {
|
|
14
|
+
slug: string;
|
|
15
|
+
};
|
|
16
|
+
runId: string;
|
|
17
|
+
recipients: string[];
|
|
18
|
+
subject: string;
|
|
19
|
+
body: string;
|
|
20
|
+
}): Promise<{
|
|
21
|
+
status: "completed";
|
|
22
|
+
summary: string;
|
|
23
|
+
deliveredCount: number;
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
export declare function createNotificationAdapter(): StubNotificationAdapter | SdkMessageNotificationAdapter;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { AgentSdk } from "@treeseed/sdk";
|
|
2
|
+
import { resolveTreeseedTenantRoot } from "@treeseed/sdk/platform/tenant-config";
|
|
3
|
+
import { getTreeseedAgentProviderSelections } from "@treeseed/sdk/platform/deploy-runtime";
|
|
4
|
+
class StubNotificationAdapter {
|
|
5
|
+
async deliver(input) {
|
|
6
|
+
return {
|
|
7
|
+
status: input.recipients.length ? "completed" : "waiting",
|
|
8
|
+
summary: input.recipients.length ? `Prepared ${input.recipients.length} notification(s).` : "No recipients available for notification.",
|
|
9
|
+
deliveredCount: input.recipients.length
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
class SdkMessageNotificationAdapter {
|
|
14
|
+
async deliver(input) {
|
|
15
|
+
const sdk = AgentSdk.createLocal({ repoRoot: resolveTreeseedTenantRoot() });
|
|
16
|
+
await sdk.createMessage({
|
|
17
|
+
type: "agent.notification",
|
|
18
|
+
payload: {
|
|
19
|
+
agentSlug: input.agent.slug,
|
|
20
|
+
runId: input.runId,
|
|
21
|
+
recipients: input.recipients,
|
|
22
|
+
subject: input.subject,
|
|
23
|
+
body: input.body,
|
|
24
|
+
summary: `Prepared ${input.recipients.length} notification(s).`
|
|
25
|
+
},
|
|
26
|
+
relatedModel: "agent",
|
|
27
|
+
relatedId: input.agent.slug,
|
|
28
|
+
actor: "agent"
|
|
29
|
+
});
|
|
30
|
+
return {
|
|
31
|
+
status: "completed",
|
|
32
|
+
summary: input.recipients.length ? `Prepared ${input.recipients.length} notification(s).` : "Notification recorded without recipients.",
|
|
33
|
+
deliveredCount: input.recipients.length
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function createNotificationAdapter() {
|
|
38
|
+
return String(
|
|
39
|
+
process.env.TREESEED_AGENT_NOTIFICATION_PROVIDER ?? getTreeseedAgentProviderSelections().notification
|
|
40
|
+
).toLowerCase() === "sdk_message" ? new SdkMessageNotificationAdapter() : new StubNotificationAdapter();
|
|
41
|
+
}
|
|
42
|
+
export {
|
|
43
|
+
SdkMessageNotificationAdapter,
|
|
44
|
+
StubNotificationAdapter,
|
|
45
|
+
createNotificationAdapter
|
|
46
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AgentRepositoryInspectionAdapter } from '../runtime-types.ts';
|
|
2
|
+
export declare class StubRepositoryInspectionAdapter implements AgentRepositoryInspectionAdapter {
|
|
3
|
+
inspectBranch(input: {
|
|
4
|
+
branchName: string | null;
|
|
5
|
+
}): Promise<{
|
|
6
|
+
branchName: string | null;
|
|
7
|
+
changedPaths: never[];
|
|
8
|
+
commitSha: null;
|
|
9
|
+
summary: string;
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
12
|
+
export declare class GitRepositoryInspectionAdapter implements AgentRepositoryInspectionAdapter {
|
|
13
|
+
inspectBranch(input: {
|
|
14
|
+
repoRoot: string;
|
|
15
|
+
branchName: string | null;
|
|
16
|
+
}): Promise<{
|
|
17
|
+
branchName: null;
|
|
18
|
+
changedPaths: never[];
|
|
19
|
+
commitSha: null;
|
|
20
|
+
summary: string;
|
|
21
|
+
} | {
|
|
22
|
+
branchName: string;
|
|
23
|
+
changedPaths: string[];
|
|
24
|
+
commitSha: string | null;
|
|
25
|
+
summary: string;
|
|
26
|
+
}>;
|
|
27
|
+
}
|
|
28
|
+
export declare function createRepositoryInspectionAdapter(): StubRepositoryInspectionAdapter | GitRepositoryInspectionAdapter;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import { getTreeseedAgentProviderSelections } from "@treeseed/sdk/platform/deploy-runtime";
|
|
4
|
+
const execFileAsync = promisify(execFile);
|
|
5
|
+
class StubRepositoryInspectionAdapter {
|
|
6
|
+
async inspectBranch(input) {
|
|
7
|
+
return {
|
|
8
|
+
branchName: input.branchName,
|
|
9
|
+
changedPaths: [],
|
|
10
|
+
commitSha: null,
|
|
11
|
+
summary: input.branchName ? `Stub repository inspection for ${input.branchName}.` : "No branch to inspect."
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
class GitRepositoryInspectionAdapter {
|
|
16
|
+
async inspectBranch(input) {
|
|
17
|
+
if (!input.branchName) {
|
|
18
|
+
return {
|
|
19
|
+
branchName: null,
|
|
20
|
+
changedPaths: [],
|
|
21
|
+
commitSha: null,
|
|
22
|
+
summary: "No branch to inspect."
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const { stdout: changedStdout } = await execFileAsync(
|
|
27
|
+
"git",
|
|
28
|
+
["diff", "--name-only", "HEAD~1..HEAD"],
|
|
29
|
+
{ cwd: input.repoRoot, env: process.env }
|
|
30
|
+
);
|
|
31
|
+
const { stdout: shaStdout } = await execFileAsync("git", ["rev-parse", "HEAD"], {
|
|
32
|
+
cwd: input.repoRoot,
|
|
33
|
+
env: process.env
|
|
34
|
+
});
|
|
35
|
+
const changedPaths = changedStdout.split("\n").map((entry) => entry.trim()).filter(Boolean);
|
|
36
|
+
return {
|
|
37
|
+
branchName: input.branchName,
|
|
38
|
+
changedPaths,
|
|
39
|
+
commitSha: shaStdout.trim() || null,
|
|
40
|
+
summary: `Inspected ${changedPaths.length} changed path(s) on ${input.branchName}.`
|
|
41
|
+
};
|
|
42
|
+
} catch {
|
|
43
|
+
return {
|
|
44
|
+
branchName: input.branchName,
|
|
45
|
+
changedPaths: [],
|
|
46
|
+
commitSha: null,
|
|
47
|
+
summary: `Unable to inspect branch ${input.branchName}.`
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function createRepositoryInspectionAdapter() {
|
|
53
|
+
return String(
|
|
54
|
+
process.env.TREESEED_AGENT_REPOSITORY_PROVIDER ?? getTreeseedAgentProviderSelections().repository
|
|
55
|
+
).toLowerCase() !== "git" ? new StubRepositoryInspectionAdapter() : new GitRepositoryInspectionAdapter();
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
GitRepositoryInspectionAdapter,
|
|
59
|
+
StubRepositoryInspectionAdapter,
|
|
60
|
+
createRepositoryInspectionAdapter
|
|
61
|
+
};
|