bopodev-agent-sdk 0.1.28 → 0.1.30
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 +1 -1
- package/.turbo/turbo-lint.log +4 -0
- package/.turbo/turbo-typecheck.log +1 -1
- package/dist/adapters/codex/src/server/quota.d.ts +2 -0
- package/dist/adapters/openclaw-gateway/src/cli/format-event.d.ts +1 -0
- package/dist/adapters/openclaw-gateway/src/cli/index.d.ts +1 -0
- package/dist/adapters/openclaw-gateway/src/index.d.ts +7 -0
- package/dist/adapters/openclaw-gateway/src/server/device-auth.d.ts +25 -0
- package/dist/adapters/openclaw-gateway/src/server/execute.d.ts +2 -0
- package/dist/adapters/openclaw-gateway/src/server/gateway-client.d.ts +56 -0
- package/dist/adapters/openclaw-gateway/src/server/index.d.ts +2 -0
- package/dist/adapters/openclaw-gateway/src/server/parse.d.ts +22 -0
- package/dist/adapters/openclaw-gateway/src/server/test.d.ts +2 -0
- package/dist/adapters/openclaw-gateway/src/ui/build-config.d.ts +3 -0
- package/dist/adapters/openclaw-gateway/src/ui/index.d.ts +2 -0
- package/dist/adapters/openclaw-gateway/src/ui/parse-stdout.d.ts +6 -0
- package/dist/adapters/opencode/src/index.d.ts +5 -1
- package/dist/agent-sdk/src/quota.d.ts +4 -0
- package/dist/agent-sdk/src/types.d.ts +13 -0
- package/dist/contracts/src/index.d.ts +43 -0
- package/package.json +2 -2
- package/src/adapters.ts +118 -11
- package/src/registry.ts +19 -4
- package/src/types.ts +13 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
> bopodev-agent-sdk@0.1.
|
|
3
|
+
> bopodev-agent-sdk@0.1.30 build /Users/danielkrusenstrahle/Documents/Projects/Monorepo/bopohq/packages/agent-sdk
|
|
4
4
|
> tsc -p tsconfig.json --emitDeclarationOnly
|
|
5
5
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
|
|
2
|
-
> bopodev-agent-sdk@0.1.
|
|
2
|
+
> bopodev-agent-sdk@0.1.29 typecheck /Users/danielkrusenstrahle/Documents/Projects/Monorepo/bopohq/packages/agent-sdk
|
|
3
3
|
> tsc -p tsconfig.json --noEmit
|
|
4
4
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function formatStdoutEvent(line: string, debug: boolean): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { formatStdoutEvent } from "./format-event";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AdapterMetadata, AdapterModule } from "../../../agent-sdk/src/types";
|
|
2
|
+
export declare const type: "openclaw_gateway";
|
|
3
|
+
export declare const label = "OpenClaw Gateway";
|
|
4
|
+
export declare const models: readonly [];
|
|
5
|
+
export declare const agentConfigurationDoc = "Use when:\n- You run a self-hosted [OpenClaw](https://docs.openclaw.ai/) gateway and want Bopo heartbeats to invoke `agent` / `agent.wait` over the documented WebSocket protocol.\n\nConfigure:\n- **Command**: WebSocket URL (e.g. `ws://127.0.0.1:18789`). Alternatively set `OPENCLAW_GATEWAY_URL` in runtime environment.\n- **Runtime environment**: `OPENCLAW_GATEWAY_TOKEN` or `OPENCLAW_GATEWAY_PASSWORD` (required). Optional: `OPENCLAW_AGENT_ID`, `OPENCLAW_SESSION_KEY`, `OPENCLAW_SESSION_KEY_STRATEGY` (`issue` | `run` | `fixed`), `OPENCLAW_AGENT_WAIT_MS`, `OPENCLAW_DEVICE_PRIVATE_KEY_PEM` (stable device identity), `BOPO_OPENCLAW_DISABLE_DEVICE_AUTH=1` only if your gateway explicitly allows insecure mode.\n\nDo not use when:\n- You need a local CLI subprocess adapter \u2014 use Codex, Claude Code, or OpenCode instead.";
|
|
6
|
+
export declare const metadata: AdapterMetadata;
|
|
7
|
+
export declare const openclawGatewayAdapterModule: AdapterModule;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare function publicKeyRawBase64UrlFromPem(publicKeyPem: string): string;
|
|
2
|
+
export declare function signDevicePayload(privateKeyPem: string, payload: string): string;
|
|
3
|
+
export type OpenClawDeviceIdentity = {
|
|
4
|
+
deviceId: string;
|
|
5
|
+
publicKeyPem: string;
|
|
6
|
+
privateKeyPem: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function generateEphemeralDeviceIdentity(): OpenClawDeviceIdentity;
|
|
9
|
+
export declare function loadDeviceIdentityFromPrivateKeyPem(privateKeyPem: string): OpenClawDeviceIdentity;
|
|
10
|
+
/**
|
|
11
|
+
* OpenClaw gateway device signing payload (v3), compatible with gateway verification.
|
|
12
|
+
* @see https://docs.openclaw.ai/gateway/protocol
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildOpenClawDeviceAuthPayloadV3(params: {
|
|
15
|
+
deviceId: string;
|
|
16
|
+
clientId: string;
|
|
17
|
+
clientMode: string;
|
|
18
|
+
role: string;
|
|
19
|
+
scopes: string[];
|
|
20
|
+
signedAtMs: number;
|
|
21
|
+
token?: string | null;
|
|
22
|
+
nonce: string;
|
|
23
|
+
platform?: string | null;
|
|
24
|
+
deviceFamily?: string | null;
|
|
25
|
+
}): string;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type ParsedOpenClawSessionUsage } from "./parse";
|
|
2
|
+
export declare class GatewayResponseError extends Error {
|
|
3
|
+
readonly gatewayCode?: string;
|
|
4
|
+
readonly gatewayDetails?: unknown;
|
|
5
|
+
constructor(message: string, gatewayCode?: string, gatewayDetails?: unknown);
|
|
6
|
+
}
|
|
7
|
+
export type OpenClawGatewayRunOptions = {
|
|
8
|
+
gatewayUrl: string;
|
|
9
|
+
token?: string | null;
|
|
10
|
+
password?: string | null;
|
|
11
|
+
devicePrivateKeyPem?: string | null;
|
|
12
|
+
/** When true, omit `device` on `connect` (gateway must allow disabled device auth). */
|
|
13
|
+
disableDeviceAuth?: boolean;
|
|
14
|
+
agentId?: string | null;
|
|
15
|
+
/** For `sessionKeyStrategy: "fixed"` — OpenClaw session key string. */
|
|
16
|
+
openclawSessionKey?: string | null;
|
|
17
|
+
sessionKeyStrategy?: "issue" | "run" | "fixed";
|
|
18
|
+
primaryIssueId?: string | null;
|
|
19
|
+
/** OpenClaw `agent.timeout` (seconds). */
|
|
20
|
+
agentTimeoutSec?: number | null;
|
|
21
|
+
model?: string | null;
|
|
22
|
+
message: string;
|
|
23
|
+
idempotencyKey: string;
|
|
24
|
+
connectTimeoutMs: number;
|
|
25
|
+
agentWaitTimeoutMs: number;
|
|
26
|
+
onStdoutLine: (line: string) => void;
|
|
27
|
+
onTranscriptEvent?: (event: {
|
|
28
|
+
kind: "system" | "assistant" | "thinking" | "tool_call" | "tool_result" | "result" | "stderr";
|
|
29
|
+
label?: string;
|
|
30
|
+
text?: string;
|
|
31
|
+
payload?: string;
|
|
32
|
+
signalLevel?: "high" | "medium" | "low" | "noise";
|
|
33
|
+
groupKey?: string;
|
|
34
|
+
source?: "stdout" | "stderr";
|
|
35
|
+
}) => void;
|
|
36
|
+
abortSignal?: AbortSignal;
|
|
37
|
+
};
|
|
38
|
+
export type OpenClawGatewayRunResult = {
|
|
39
|
+
ok: boolean;
|
|
40
|
+
summary: string;
|
|
41
|
+
runId?: string;
|
|
42
|
+
timedOut?: boolean;
|
|
43
|
+
errorMessage?: string;
|
|
44
|
+
tokenInput: number;
|
|
45
|
+
tokenOutput: number;
|
|
46
|
+
/** Cache / context read tokens when reported by `sessions.usage`. */
|
|
47
|
+
cachedInputTokens: number;
|
|
48
|
+
usdCost: number;
|
|
49
|
+
model?: string | null;
|
|
50
|
+
/** Resolved OpenClaw runtime model provider (e.g. anthropic), when available. */
|
|
51
|
+
openclawModelProvider?: string | null;
|
|
52
|
+
provider?: string | null;
|
|
53
|
+
/** Where token/model/cost metadata came from, for traces. */
|
|
54
|
+
openclawUsageSource?: ParsedOpenClawSessionUsage["source"] | "none";
|
|
55
|
+
};
|
|
56
|
+
export declare function runOpenClawGatewayTurn(options: OpenClawGatewayRunOptions): Promise<OpenClawGatewayRunResult>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse OpenClaw gateway JSON payloads for session usage (tokens, model, cost).
|
|
3
|
+
* Shapes follow `sessions.list` / `sessions.usage` responses on the gateway WebSocket API.
|
|
4
|
+
*/
|
|
5
|
+
export type ParsedOpenClawSessionUsage = {
|
|
6
|
+
tokenInput: number;
|
|
7
|
+
tokenOutput: number;
|
|
8
|
+
cachedInputTokens: number;
|
|
9
|
+
usdCost: number;
|
|
10
|
+
model: string | null;
|
|
11
|
+
modelProvider: string | null;
|
|
12
|
+
source: "sessions.list" | "sessions.usage";
|
|
13
|
+
};
|
|
14
|
+
/** Match `GatewaySessionRow` from OpenClaw `sessions.list` (search + exact key). */
|
|
15
|
+
export declare function extractUsageFromSessionsList(payload: unknown, exactSessionKey: string): ParsedOpenClawSessionUsage | null;
|
|
16
|
+
/** Match `SessionUsageEntry` from OpenClaw `sessions.usage` when `key` is scoped. */
|
|
17
|
+
export declare function extractUsageFromSessionsUsage(payload: unknown, exactSessionKey: string): ParsedOpenClawSessionUsage | null;
|
|
18
|
+
/**
|
|
19
|
+
* Map OpenClaw session `modelProvider` strings to Bopo `pricingProviderType` when catalog pricing should apply.
|
|
20
|
+
* Returns `null` when unknown so heartbeat cost logic falls back to gateway-reported USD or `openclaw_gateway` defaults.
|
|
21
|
+
*/
|
|
22
|
+
export declare function mapOpenClawModelProviderToBopoPricingType(openclawProvider: string | null | undefined): string | null;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type { AdapterMetadata, AdapterModule } from "../../../agent-sdk/src/types";
|
|
2
2
|
export declare const type: "opencode";
|
|
3
3
|
export declare const label = "OpenCode";
|
|
4
|
-
|
|
4
|
+
/** Shown when `opencode models` is empty (e.g. CLI missing on the API host). Discovery merges on top of this. */
|
|
5
|
+
export declare const models: readonly [{
|
|
6
|
+
readonly id: "opencode/big-pickle";
|
|
7
|
+
readonly label: "Big Pickle";
|
|
8
|
+
}];
|
|
5
9
|
export declare const agentConfigurationDoc = "Use when:\n- You need OpenCode CLI execution with provider/model selection.\n- You want OpenCode session reuse.\n\nDo not use when:\n- No runtime model is configured.\n- The host cannot run OpenCode CLI.";
|
|
6
10
|
export declare const metadata: AdapterMetadata;
|
|
7
11
|
export declare const opencodeAdapterModule: AdapterModule;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AgentProviderType, AdapterQuotaProbeResult, AgentRuntimeConfig } from "./types";
|
|
2
|
+
export declare function createUnsupportedQuotaProbeResult(providerType: AgentProviderType, message: string): AdapterQuotaProbeResult;
|
|
3
|
+
export declare function createAuthRequiredQuotaProbeResult(providerType: AgentProviderType, message: string): AdapterQuotaProbeResult;
|
|
4
|
+
export declare function resolveMergedEnv(runtime?: AgentRuntimeConfig): NodeJS.ProcessEnv;
|
|
@@ -4,6 +4,10 @@ export interface AgentWorkItem {
|
|
|
4
4
|
issueId: string;
|
|
5
5
|
projectId: string;
|
|
6
6
|
parentIssueId?: string | null;
|
|
7
|
+
/** Linked planning goals for this issue, if any. */
|
|
8
|
+
goalIds?: string[];
|
|
9
|
+
/** Root-to-leaf chain per linked goal (same order as goalIds). */
|
|
10
|
+
goalAncestryChains?: string[][];
|
|
7
11
|
childIssueIds?: string[];
|
|
8
12
|
projectName?: string | null;
|
|
9
13
|
title: string;
|
|
@@ -75,6 +79,15 @@ export interface HeartbeatContext {
|
|
|
75
79
|
commentBody?: string | null;
|
|
76
80
|
issueIds?: string[];
|
|
77
81
|
};
|
|
82
|
+
/** Company agents (non-terminated), sorted by name; used for delegation and task routing hints. */
|
|
83
|
+
teamRoster?: Array<{
|
|
84
|
+
id: string;
|
|
85
|
+
name: string;
|
|
86
|
+
role: string;
|
|
87
|
+
title?: string | null;
|
|
88
|
+
capabilities?: string | null;
|
|
89
|
+
status: string;
|
|
90
|
+
}>;
|
|
78
91
|
}
|
|
79
92
|
/**
|
|
80
93
|
* Normalized usage contract produced by adapter execution.
|
|
@@ -127,8 +127,10 @@ export declare const IssueSchema: z.ZodObject<{
|
|
|
127
127
|
companyId: z.ZodString;
|
|
128
128
|
projectId: z.ZodString;
|
|
129
129
|
parentIssueId: z.ZodNullable<z.ZodString>;
|
|
130
|
+
goalIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
130
131
|
title: z.ZodString;
|
|
131
132
|
body: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
133
|
+
externalLink: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
132
134
|
status: z.ZodEnum<{
|
|
133
135
|
blocked: "blocked";
|
|
134
136
|
todo: "todo";
|
|
@@ -192,8 +194,10 @@ export declare const IssueDetailSchema: z.ZodObject<{
|
|
|
192
194
|
companyId: z.ZodString;
|
|
193
195
|
projectId: z.ZodString;
|
|
194
196
|
parentIssueId: z.ZodNullable<z.ZodString>;
|
|
197
|
+
goalIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
195
198
|
title: z.ZodString;
|
|
196
199
|
body: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
200
|
+
externalLink: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
197
201
|
status: z.ZodEnum<{
|
|
198
202
|
blocked: "blocked";
|
|
199
203
|
todo: "todo";
|
|
@@ -310,6 +314,7 @@ export declare const GoalSchema: z.ZodObject<{
|
|
|
310
314
|
companyId: z.ZodString;
|
|
311
315
|
projectId: z.ZodNullable<z.ZodString>;
|
|
312
316
|
parentGoalId: z.ZodNullable<z.ZodString>;
|
|
317
|
+
ownerAgentId: z.ZodNullable<z.ZodString>;
|
|
313
318
|
level: z.ZodEnum<{
|
|
314
319
|
agent: "agent";
|
|
315
320
|
company: "company";
|
|
@@ -400,6 +405,7 @@ export declare const TemplateManifestAgentSchema: z.ZodObject<{
|
|
|
400
405
|
general: "general";
|
|
401
406
|
}>>;
|
|
402
407
|
title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
408
|
+
capabilities: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
403
409
|
name: z.ZodString;
|
|
404
410
|
providerType: z.ZodDefault<z.ZodLazy<z.ZodEnum<{
|
|
405
411
|
claude_code: "claude_code";
|
|
@@ -409,6 +415,7 @@ export declare const TemplateManifestAgentSchema: z.ZodObject<{
|
|
|
409
415
|
gemini_cli: "gemini_cli";
|
|
410
416
|
openai_api: "openai_api";
|
|
411
417
|
anthropic_api: "anthropic_api";
|
|
418
|
+
openclaw_gateway: "openclaw_gateway";
|
|
412
419
|
http: "http";
|
|
413
420
|
shell: "shell";
|
|
414
421
|
}>>>;
|
|
@@ -527,6 +534,7 @@ export declare const TemplateManifestSchema: z.ZodObject<{
|
|
|
527
534
|
general: "general";
|
|
528
535
|
}>>;
|
|
529
536
|
title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
537
|
+
capabilities: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
530
538
|
name: z.ZodString;
|
|
531
539
|
providerType: z.ZodDefault<z.ZodLazy<z.ZodEnum<{
|
|
532
540
|
claude_code: "claude_code";
|
|
@@ -536,6 +544,7 @@ export declare const TemplateManifestSchema: z.ZodObject<{
|
|
|
536
544
|
gemini_cli: "gemini_cli";
|
|
537
545
|
openai_api: "openai_api";
|
|
538
546
|
anthropic_api: "anthropic_api";
|
|
547
|
+
openclaw_gateway: "openclaw_gateway";
|
|
539
548
|
http: "http";
|
|
540
549
|
shell: "shell";
|
|
541
550
|
}>>>;
|
|
@@ -687,6 +696,7 @@ export declare const TemplateSchema: z.ZodObject<{
|
|
|
687
696
|
general: "general";
|
|
688
697
|
}>>;
|
|
689
698
|
title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
699
|
+
capabilities: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
690
700
|
name: z.ZodString;
|
|
691
701
|
providerType: z.ZodDefault<z.ZodLazy<z.ZodEnum<{
|
|
692
702
|
claude_code: "claude_code";
|
|
@@ -696,6 +706,7 @@ export declare const TemplateSchema: z.ZodObject<{
|
|
|
696
706
|
gemini_cli: "gemini_cli";
|
|
697
707
|
openai_api: "openai_api";
|
|
698
708
|
anthropic_api: "anthropic_api";
|
|
709
|
+
openclaw_gateway: "openclaw_gateway";
|
|
699
710
|
http: "http";
|
|
700
711
|
shell: "shell";
|
|
701
712
|
}>>>;
|
|
@@ -847,6 +858,7 @@ export declare const TemplateCreateRequestSchema: z.ZodObject<{
|
|
|
847
858
|
general: "general";
|
|
848
859
|
}>>;
|
|
849
860
|
title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
861
|
+
capabilities: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
850
862
|
name: z.ZodString;
|
|
851
863
|
providerType: z.ZodDefault<z.ZodLazy<z.ZodEnum<{
|
|
852
864
|
claude_code: "claude_code";
|
|
@@ -856,6 +868,7 @@ export declare const TemplateCreateRequestSchema: z.ZodObject<{
|
|
|
856
868
|
gemini_cli: "gemini_cli";
|
|
857
869
|
openai_api: "openai_api";
|
|
858
870
|
anthropic_api: "anthropic_api";
|
|
871
|
+
openclaw_gateway: "openclaw_gateway";
|
|
859
872
|
http: "http";
|
|
860
873
|
shell: "shell";
|
|
861
874
|
}>>>;
|
|
@@ -1005,6 +1018,7 @@ export declare const TemplateUpdateRequestSchema: z.ZodObject<{
|
|
|
1005
1018
|
general: "general";
|
|
1006
1019
|
}>>;
|
|
1007
1020
|
title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1021
|
+
capabilities: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1008
1022
|
name: z.ZodString;
|
|
1009
1023
|
providerType: z.ZodDefault<z.ZodLazy<z.ZodEnum<{
|
|
1010
1024
|
claude_code: "claude_code";
|
|
@@ -1014,6 +1028,7 @@ export declare const TemplateUpdateRequestSchema: z.ZodObject<{
|
|
|
1014
1028
|
gemini_cli: "gemini_cli";
|
|
1015
1029
|
openai_api: "openai_api";
|
|
1016
1030
|
anthropic_api: "anthropic_api";
|
|
1031
|
+
openclaw_gateway: "openclaw_gateway";
|
|
1017
1032
|
http: "http";
|
|
1018
1033
|
shell: "shell";
|
|
1019
1034
|
}>>>;
|
|
@@ -1214,6 +1229,7 @@ export declare const TemplateExportSchema: z.ZodObject<{
|
|
|
1214
1229
|
general: "general";
|
|
1215
1230
|
}>>;
|
|
1216
1231
|
title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1232
|
+
capabilities: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1217
1233
|
name: z.ZodString;
|
|
1218
1234
|
providerType: z.ZodDefault<z.ZodLazy<z.ZodEnum<{
|
|
1219
1235
|
claude_code: "claude_code";
|
|
@@ -1223,6 +1239,7 @@ export declare const TemplateExportSchema: z.ZodObject<{
|
|
|
1223
1239
|
gemini_cli: "gemini_cli";
|
|
1224
1240
|
openai_api: "openai_api";
|
|
1225
1241
|
anthropic_api: "anthropic_api";
|
|
1242
|
+
openclaw_gateway: "openclaw_gateway";
|
|
1226
1243
|
http: "http";
|
|
1227
1244
|
shell: "shell";
|
|
1228
1245
|
}>>>;
|
|
@@ -1376,6 +1393,7 @@ export declare const TemplateImportRequestSchema: z.ZodObject<{
|
|
|
1376
1393
|
general: "general";
|
|
1377
1394
|
}>>;
|
|
1378
1395
|
title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1396
|
+
capabilities: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1379
1397
|
name: z.ZodString;
|
|
1380
1398
|
providerType: z.ZodDefault<z.ZodLazy<z.ZodEnum<{
|
|
1381
1399
|
claude_code: "claude_code";
|
|
@@ -1385,6 +1403,7 @@ export declare const TemplateImportRequestSchema: z.ZodObject<{
|
|
|
1385
1403
|
gemini_cli: "gemini_cli";
|
|
1386
1404
|
openai_api: "openai_api";
|
|
1387
1405
|
anthropic_api: "anthropic_api";
|
|
1406
|
+
openclaw_gateway: "openclaw_gateway";
|
|
1388
1407
|
http: "http";
|
|
1389
1408
|
shell: "shell";
|
|
1390
1409
|
}>>>;
|
|
@@ -1515,6 +1534,7 @@ export declare const TemplateVersionSchema: z.ZodObject<{
|
|
|
1515
1534
|
general: "general";
|
|
1516
1535
|
}>>;
|
|
1517
1536
|
title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1537
|
+
capabilities: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1518
1538
|
name: z.ZodString;
|
|
1519
1539
|
providerType: z.ZodDefault<z.ZodLazy<z.ZodEnum<{
|
|
1520
1540
|
claude_code: "claude_code";
|
|
@@ -1524,6 +1544,7 @@ export declare const TemplateVersionSchema: z.ZodObject<{
|
|
|
1524
1544
|
gemini_cli: "gemini_cli";
|
|
1525
1545
|
openai_api: "openai_api";
|
|
1526
1546
|
anthropic_api: "anthropic_api";
|
|
1547
|
+
openclaw_gateway: "openclaw_gateway";
|
|
1527
1548
|
http: "http";
|
|
1528
1549
|
shell: "shell";
|
|
1529
1550
|
}>>>;
|
|
@@ -1629,6 +1650,7 @@ export declare const ProviderTypeSchema: z.ZodEnum<{
|
|
|
1629
1650
|
gemini_cli: "gemini_cli";
|
|
1630
1651
|
openai_api: "openai_api";
|
|
1631
1652
|
anthropic_api: "anthropic_api";
|
|
1653
|
+
openclaw_gateway: "openclaw_gateway";
|
|
1632
1654
|
http: "http";
|
|
1633
1655
|
shell: "shell";
|
|
1634
1656
|
}>;
|
|
@@ -1827,6 +1849,7 @@ export declare const RunManagerReportSchema: z.ZodObject<{
|
|
|
1827
1849
|
gemini_cli: "gemini_cli";
|
|
1828
1850
|
openai_api: "openai_api";
|
|
1829
1851
|
anthropic_api: "anthropic_api";
|
|
1852
|
+
openclaw_gateway: "openclaw_gateway";
|
|
1830
1853
|
http: "http";
|
|
1831
1854
|
shell: "shell";
|
|
1832
1855
|
}>;
|
|
@@ -1904,6 +1927,7 @@ export declare const RunCompletionReportSchema: z.ZodObject<{
|
|
|
1904
1927
|
gemini_cli: "gemini_cli";
|
|
1905
1928
|
openai_api: "openai_api";
|
|
1906
1929
|
anthropic_api: "anthropic_api";
|
|
1930
|
+
openclaw_gateway: "openclaw_gateway";
|
|
1907
1931
|
http: "http";
|
|
1908
1932
|
shell: "shell";
|
|
1909
1933
|
}>;
|
|
@@ -2160,6 +2184,7 @@ export declare const AgentCreateRequestSchema: z.ZodObject<{
|
|
|
2160
2184
|
general: "general";
|
|
2161
2185
|
}>>;
|
|
2162
2186
|
title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
2187
|
+
capabilities: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
2163
2188
|
name: z.ZodString;
|
|
2164
2189
|
providerType: z.ZodEnum<{
|
|
2165
2190
|
claude_code: "claude_code";
|
|
@@ -2169,6 +2194,7 @@ export declare const AgentCreateRequestSchema: z.ZodObject<{
|
|
|
2169
2194
|
gemini_cli: "gemini_cli";
|
|
2170
2195
|
openai_api: "openai_api";
|
|
2171
2196
|
anthropic_api: "anthropic_api";
|
|
2197
|
+
openclaw_gateway: "openclaw_gateway";
|
|
2172
2198
|
http: "http";
|
|
2173
2199
|
shell: "shell";
|
|
2174
2200
|
}>;
|
|
@@ -2204,10 +2230,12 @@ export declare const AgentCreateRequestSchema: z.ZodObject<{
|
|
|
2204
2230
|
gemini_cli: "gemini_cli";
|
|
2205
2231
|
openai_api: "openai_api";
|
|
2206
2232
|
anthropic_api: "anthropic_api";
|
|
2233
|
+
openclaw_gateway: "openclaw_gateway";
|
|
2207
2234
|
http: "http";
|
|
2208
2235
|
shell: "shell";
|
|
2209
2236
|
}>>>;
|
|
2210
2237
|
requestedRuntimeModel: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
2238
|
+
requestedCapabilities: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
2211
2239
|
}, z.core.$strip>>;
|
|
2212
2240
|
requestApproval: z.ZodDefault<z.ZodBoolean>;
|
|
2213
2241
|
runtimeConfig: z.ZodDefault<z.ZodObject<{
|
|
@@ -2252,6 +2280,7 @@ export declare const AgentUpdateRequestSchema: z.ZodObject<{
|
|
|
2252
2280
|
general: "general";
|
|
2253
2281
|
}>>>;
|
|
2254
2282
|
title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
2283
|
+
capabilities: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
2255
2284
|
name: z.ZodOptional<z.ZodString>;
|
|
2256
2285
|
providerType: z.ZodOptional<z.ZodEnum<{
|
|
2257
2286
|
claude_code: "claude_code";
|
|
@@ -2261,6 +2290,7 @@ export declare const AgentUpdateRequestSchema: z.ZodObject<{
|
|
|
2261
2290
|
gemini_cli: "gemini_cli";
|
|
2262
2291
|
openai_api: "openai_api";
|
|
2263
2292
|
anthropic_api: "anthropic_api";
|
|
2293
|
+
openclaw_gateway: "openclaw_gateway";
|
|
2264
2294
|
http: "http";
|
|
2265
2295
|
shell: "shell";
|
|
2266
2296
|
}>>;
|
|
@@ -2317,6 +2347,7 @@ export declare const AgentSchema: z.ZodObject<{
|
|
|
2317
2347
|
general: "general";
|
|
2318
2348
|
}>>>;
|
|
2319
2349
|
title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
2350
|
+
capabilities: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
2320
2351
|
name: z.ZodString;
|
|
2321
2352
|
providerType: z.ZodEnum<{
|
|
2322
2353
|
claude_code: "claude_code";
|
|
@@ -2326,6 +2357,7 @@ export declare const AgentSchema: z.ZodObject<{
|
|
|
2326
2357
|
gemini_cli: "gemini_cli";
|
|
2327
2358
|
openai_api: "openai_api";
|
|
2328
2359
|
anthropic_api: "anthropic_api";
|
|
2360
|
+
openclaw_gateway: "openclaw_gateway";
|
|
2329
2361
|
http: "http";
|
|
2330
2362
|
shell: "shell";
|
|
2331
2363
|
}>;
|
|
@@ -2823,6 +2855,7 @@ export declare const OfficeOccupantSchema: z.ZodObject<{
|
|
|
2823
2855
|
gemini_cli: "gemini_cli";
|
|
2824
2856
|
openai_api: "openai_api";
|
|
2825
2857
|
anthropic_api: "anthropic_api";
|
|
2858
|
+
openclaw_gateway: "openclaw_gateway";
|
|
2826
2859
|
http: "http";
|
|
2827
2860
|
shell: "shell";
|
|
2828
2861
|
}>>;
|
|
@@ -2870,6 +2903,7 @@ export declare const OfficeSpaceEventSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
|
|
|
2870
2903
|
gemini_cli: "gemini_cli";
|
|
2871
2904
|
openai_api: "openai_api";
|
|
2872
2905
|
anthropic_api: "anthropic_api";
|
|
2906
|
+
openclaw_gateway: "openclaw_gateway";
|
|
2873
2907
|
http: "http";
|
|
2874
2908
|
shell: "shell";
|
|
2875
2909
|
}>>;
|
|
@@ -2916,6 +2950,7 @@ export declare const OfficeSpaceEventSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
|
|
|
2916
2950
|
gemini_cli: "gemini_cli";
|
|
2917
2951
|
openai_api: "openai_api";
|
|
2918
2952
|
anthropic_api: "anthropic_api";
|
|
2953
|
+
openclaw_gateway: "openclaw_gateway";
|
|
2919
2954
|
http: "http";
|
|
2920
2955
|
shell: "shell";
|
|
2921
2956
|
}>>;
|
|
@@ -3209,6 +3244,7 @@ export declare const RealtimeEventEnvelopeSchema: z.ZodDiscriminatedUnion<[z.Zod
|
|
|
3209
3244
|
gemini_cli: "gemini_cli";
|
|
3210
3245
|
openai_api: "openai_api";
|
|
3211
3246
|
anthropic_api: "anthropic_api";
|
|
3247
|
+
openclaw_gateway: "openclaw_gateway";
|
|
3212
3248
|
http: "http";
|
|
3213
3249
|
shell: "shell";
|
|
3214
3250
|
}>>;
|
|
@@ -3255,6 +3291,7 @@ export declare const RealtimeEventEnvelopeSchema: z.ZodDiscriminatedUnion<[z.Zod
|
|
|
3255
3291
|
gemini_cli: "gemini_cli";
|
|
3256
3292
|
openai_api: "openai_api";
|
|
3257
3293
|
anthropic_api: "anthropic_api";
|
|
3294
|
+
openclaw_gateway: "openclaw_gateway";
|
|
3258
3295
|
http: "http";
|
|
3259
3296
|
shell: "shell";
|
|
3260
3297
|
}>>;
|
|
@@ -3636,6 +3673,7 @@ export declare const RealtimeEventMessageSchema: z.ZodDiscriminatedUnion<[z.ZodO
|
|
|
3636
3673
|
gemini_cli: "gemini_cli";
|
|
3637
3674
|
openai_api: "openai_api";
|
|
3638
3675
|
anthropic_api: "anthropic_api";
|
|
3676
|
+
openclaw_gateway: "openclaw_gateway";
|
|
3639
3677
|
http: "http";
|
|
3640
3678
|
shell: "shell";
|
|
3641
3679
|
}>>;
|
|
@@ -3682,6 +3720,7 @@ export declare const RealtimeEventMessageSchema: z.ZodDiscriminatedUnion<[z.ZodO
|
|
|
3682
3720
|
gemini_cli: "gemini_cli";
|
|
3683
3721
|
openai_api: "openai_api";
|
|
3684
3722
|
anthropic_api: "anthropic_api";
|
|
3723
|
+
openclaw_gateway: "openclaw_gateway";
|
|
3685
3724
|
http: "http";
|
|
3686
3725
|
shell: "shell";
|
|
3687
3726
|
}>>;
|
|
@@ -4065,6 +4104,7 @@ export declare const RealtimeMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
4065
4104
|
gemini_cli: "gemini_cli";
|
|
4066
4105
|
openai_api: "openai_api";
|
|
4067
4106
|
anthropic_api: "anthropic_api";
|
|
4107
|
+
openclaw_gateway: "openclaw_gateway";
|
|
4068
4108
|
http: "http";
|
|
4069
4109
|
shell: "shell";
|
|
4070
4110
|
}>>;
|
|
@@ -4111,6 +4151,7 @@ export declare const RealtimeMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
4111
4151
|
gemini_cli: "gemini_cli";
|
|
4112
4152
|
openai_api: "openai_api";
|
|
4113
4153
|
anthropic_api: "anthropic_api";
|
|
4154
|
+
openclaw_gateway: "openclaw_gateway";
|
|
4114
4155
|
http: "http";
|
|
4115
4156
|
shell: "shell";
|
|
4116
4157
|
}>>;
|
|
@@ -4381,6 +4422,7 @@ export declare const CostLedgerEntrySchema: z.ZodObject<{
|
|
|
4381
4422
|
gemini_cli: "gemini_cli";
|
|
4382
4423
|
openai_api: "openai_api";
|
|
4383
4424
|
anthropic_api: "anthropic_api";
|
|
4425
|
+
openclaw_gateway: "openclaw_gateway";
|
|
4384
4426
|
http: "http";
|
|
4385
4427
|
shell: "shell";
|
|
4386
4428
|
}>;
|
|
@@ -4663,6 +4705,7 @@ export declare const HeartbeatRunDetailSchema: z.ZodObject<{
|
|
|
4663
4705
|
gemini_cli: "gemini_cli";
|
|
4664
4706
|
openai_api: "openai_api";
|
|
4665
4707
|
anthropic_api: "anthropic_api";
|
|
4708
|
+
openclaw_gateway: "openclaw_gateway";
|
|
4666
4709
|
http: "http";
|
|
4667
4710
|
shell: "shell";
|
|
4668
4711
|
}>;
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bopodev-agent-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.30",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"types": "src/index.ts",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"bopodev-contracts": "0.1.
|
|
9
|
+
"bopodev-contracts": "0.1.30"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
12
|
"build": "tsc -p tsconfig.json --emitDeclarationOnly",
|
package/src/adapters.ts
CHANGED
|
@@ -11,7 +11,11 @@ import type {
|
|
|
11
11
|
HeartbeatContext,
|
|
12
12
|
HeartbeatPromptMode
|
|
13
13
|
} from "./types";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
ExecutionOutcomeSchema,
|
|
16
|
+
type AgentFinalRunOutput,
|
|
17
|
+
type ExecutionOutcome
|
|
18
|
+
} from "bopodev-contracts";
|
|
15
19
|
import {
|
|
16
20
|
checkRuntimeCommandHealth,
|
|
17
21
|
containsUsageLimitHardStopFailure,
|
|
@@ -161,6 +165,32 @@ function toNormalizedUsage(usage: RuntimeParsedUsage | undefined): AdapterNormal
|
|
|
161
165
|
};
|
|
162
166
|
}
|
|
163
167
|
|
|
168
|
+
/**
|
|
169
|
+
* Cursor and Gemini CLIs emit stream-json transcripts with usage, not a standalone heartbeat JSON blob.
|
|
170
|
+
* When structured usage was resolved from the stream but no final JSON object exists, synthesize the
|
|
171
|
+
* minimal contract shape so downstream heartbeat persistence stays consistent.
|
|
172
|
+
*/
|
|
173
|
+
function synthesizeStreamFinalRunOutput(
|
|
174
|
+
provider: AgentProviderType,
|
|
175
|
+
parsedUsage: RuntimeParsedUsage | undefined
|
|
176
|
+
): AgentFinalRunOutput | null {
|
|
177
|
+
if (provider !== "cursor" && provider !== "gemini_cli") {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
if (!parsedUsage) {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
const summary =
|
|
184
|
+
(typeof parsedUsage.summary === "string" && parsedUsage.summary.trim()) ||
|
|
185
|
+
`${provider} runtime completed.`;
|
|
186
|
+
return {
|
|
187
|
+
employee_comment: summary,
|
|
188
|
+
results: [],
|
|
189
|
+
errors: [],
|
|
190
|
+
artifacts: []
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
164
194
|
function usageTokenInputTotal(usage: RuntimeParsedUsage | undefined) {
|
|
165
195
|
if (!usage) {
|
|
166
196
|
return 0;
|
|
@@ -656,6 +686,15 @@ const staticMetadata: AdapterMetadata[] = [
|
|
|
656
686
|
supportsThinkingEffort: false,
|
|
657
687
|
requiresRuntimeCwd: false
|
|
658
688
|
},
|
|
689
|
+
{
|
|
690
|
+
providerType: "openclaw_gateway",
|
|
691
|
+
label: "OpenClaw Gateway",
|
|
692
|
+
supportsModelSelection: false,
|
|
693
|
+
supportsEnvironmentTest: true,
|
|
694
|
+
supportsWebSearch: false,
|
|
695
|
+
supportsThinkingEffort: false,
|
|
696
|
+
requiresRuntimeCwd: false
|
|
697
|
+
},
|
|
659
698
|
{
|
|
660
699
|
providerType: "http",
|
|
661
700
|
label: "HTTP",
|
|
@@ -678,7 +717,7 @@ const staticMetadata: AdapterMetadata[] = [
|
|
|
678
717
|
|
|
679
718
|
const metadataByProviderType = new Map(staticMetadata.map((entry) => [entry.providerType, entry] as const));
|
|
680
719
|
|
|
681
|
-
const modelCatalog: Record<Exclude<AgentProviderType, "http" | "shell">, AdapterModelOption[]> = {
|
|
720
|
+
const modelCatalog: Record<Exclude<AgentProviderType, "http" | "shell" | "openclaw_gateway">, AdapterModelOption[]> = {
|
|
682
721
|
codex: [
|
|
683
722
|
{ id: "gpt-5.3-codex", label: "GPT-5.3 Codex" },
|
|
684
723
|
{ id: "gpt-5.4", label: "GPT-5.4" },
|
|
@@ -741,7 +780,7 @@ export async function listAdapterModels(
|
|
|
741
780
|
providerType: AgentProviderType,
|
|
742
781
|
runtime?: AgentRuntimeConfig
|
|
743
782
|
): Promise<AdapterModelOption[]> {
|
|
744
|
-
if (providerType === "http" || providerType === "shell") {
|
|
783
|
+
if (providerType === "http" || providerType === "shell" || providerType === "openclaw_gateway") {
|
|
745
784
|
return [];
|
|
746
785
|
}
|
|
747
786
|
if (providerType === "cursor") {
|
|
@@ -870,7 +909,10 @@ export async function testAdapterEnvironment(
|
|
|
870
909
|
|
|
871
910
|
function detectProviderCommandMismatch(providerType: AgentProviderType, command: string) {
|
|
872
911
|
const normalized = basename(command).toLowerCase();
|
|
873
|
-
const known: Record<
|
|
912
|
+
const known: Record<
|
|
913
|
+
Exclude<AgentProviderType, "http" | "shell" | "openai_api" | "anthropic_api" | "openclaw_gateway">,
|
|
914
|
+
string[]
|
|
915
|
+
> = {
|
|
874
916
|
claude_code: ["claude", "claude.exe", "claude.cmd"],
|
|
875
917
|
codex: ["codex", "codex.exe", "codex.cmd"],
|
|
876
918
|
cursor: ["cursor", "cursor.exe", "cursor.cmd"],
|
|
@@ -1850,7 +1892,9 @@ export function toProviderResult(
|
|
|
1850
1892
|
nextState: applyProviderSessionState(context, provider, sessionUpdate)
|
|
1851
1893
|
};
|
|
1852
1894
|
}
|
|
1853
|
-
|
|
1895
|
+
const resolvedFinalRunOutput =
|
|
1896
|
+
runtime.finalRunOutput ?? synthesizeStreamFinalRunOutput(provider, runtime.parsedUsage);
|
|
1897
|
+
if (!resolvedFinalRunOutput) {
|
|
1854
1898
|
const usage = toNormalizedUsage(runtime.parsedUsage);
|
|
1855
1899
|
const detail = resolveFinalRunOutputContractDetail({ provider, runtime });
|
|
1856
1900
|
return createContractInvalidResult({
|
|
@@ -1895,7 +1939,7 @@ export function toProviderResult(
|
|
|
1895
1939
|
tokenInput: usageTokenInputTotal(runtime.parsedUsage),
|
|
1896
1940
|
tokenOutput,
|
|
1897
1941
|
usdCost,
|
|
1898
|
-
finalRunOutput:
|
|
1942
|
+
finalRunOutput: resolvedFinalRunOutput,
|
|
1899
1943
|
usage,
|
|
1900
1944
|
pricingProviderType,
|
|
1901
1945
|
pricingModelId,
|
|
@@ -2646,9 +2690,65 @@ function clipPromptText(text: string, max: number | null): string {
|
|
|
2646
2690
|
const HEARTBEAT_JSON_SCHEMA_FOOTER = `At the end of your response, output exactly one JSON object on a single line and nothing else. Use this exact schema:
|
|
2647
2691
|
{"employee_comment":"markdown update to the manager","results":["short concrete outcome"],"errors":[],"artifacts":[{"kind":"file","path":"relative/path"}]}`;
|
|
2648
2692
|
|
|
2693
|
+
/** Injected every heartbeat when the runtime sets BOPODEV_AGENT_OPERATING_DIR (no need to store paths in bootstrapPrompt). */
|
|
2694
|
+
function buildOperatingDirectoryPromptPrefix(context: HeartbeatContext): string {
|
|
2695
|
+
const dir = context.runtime?.env?.BOPODEV_AGENT_OPERATING_DIR?.trim();
|
|
2696
|
+
if (!dir) {
|
|
2697
|
+
return "";
|
|
2698
|
+
}
|
|
2699
|
+
return [
|
|
2700
|
+
"Operating context:",
|
|
2701
|
+
`- Your agent operating directory (read AGENTS.md, HEARTBEAT.md, SOUL.md, TOOLS.md here when they exist): ${dir}`,
|
|
2702
|
+
""
|
|
2703
|
+
].join("\n");
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2706
|
+
function composeBootstrapPreamble(context: HeartbeatContext): string {
|
|
2707
|
+
const operating = buildOperatingDirectoryPromptPrefix(context);
|
|
2708
|
+
const user = context.runtime?.bootstrapPrompt?.trim();
|
|
2709
|
+
if (!user) {
|
|
2710
|
+
return operating;
|
|
2711
|
+
}
|
|
2712
|
+
return operating ? `${operating}${user}\n\n` : `${user}\n\n`;
|
|
2713
|
+
}
|
|
2714
|
+
|
|
2715
|
+
function formatTeamRosterSection(context: HeartbeatContext): string {
|
|
2716
|
+
const roster = context.teamRoster;
|
|
2717
|
+
if (!roster?.length) {
|
|
2718
|
+
return "";
|
|
2719
|
+
}
|
|
2720
|
+
const mode = resolveHeartbeatPromptModeForPrompt(context);
|
|
2721
|
+
const isCompact = mode === "compact";
|
|
2722
|
+
const clipCapabilities = (raw: string | null | undefined) => {
|
|
2723
|
+
const t = raw?.trim();
|
|
2724
|
+
if (!t) {
|
|
2725
|
+
return null;
|
|
2726
|
+
}
|
|
2727
|
+
if (isCompact && t.length > 200) {
|
|
2728
|
+
return `${t.slice(0, 200)}…`;
|
|
2729
|
+
}
|
|
2730
|
+
return t;
|
|
2731
|
+
};
|
|
2732
|
+
const lines = roster.map((member) => {
|
|
2733
|
+
const caps = clipCapabilities(member.capabilities);
|
|
2734
|
+
const parts = [member.id, member.name, member.role];
|
|
2735
|
+
const titled = member.title?.trim();
|
|
2736
|
+
if (titled) {
|
|
2737
|
+
parts.push(`title: ${titled}`);
|
|
2738
|
+
}
|
|
2739
|
+
if (caps) {
|
|
2740
|
+
parts.push(`capabilities: ${caps}`);
|
|
2741
|
+
}
|
|
2742
|
+
const you = member.id === context.agentId ? " (you)" : "";
|
|
2743
|
+
return `- ${parts.join(" | ")}${you}`;
|
|
2744
|
+
});
|
|
2745
|
+
return ["Team roster (for delegation):", ...lines, ""].join("\n");
|
|
2746
|
+
}
|
|
2747
|
+
|
|
2649
2748
|
function buildIdleMicroPrompt(context: HeartbeatContext): string {
|
|
2650
|
-
const
|
|
2651
|
-
|
|
2749
|
+
const preamble = composeBootstrapPreamble(context);
|
|
2750
|
+
const rosterBlock = formatTeamRosterSection(context);
|
|
2751
|
+
return `${preamble}${rosterBlock}Idle heartbeat (micro prompt): agent ${context.agentId} (${context.agent.name}) has no assigned issues this run. Summarize readiness in \`employee_comment\`; leave \`results\` empty unless you completed verifiable work. Use \`BOPODEV_*\` for control-plane API calls when needed.
|
|
2652
2752
|
|
|
2653
2753
|
${HEARTBEAT_JSON_SCHEMA_FOOTER}
|
|
2654
2754
|
`;
|
|
@@ -2673,7 +2773,7 @@ export function createPrompt(context: HeartbeatContext) {
|
|
|
2673
2773
|
if (context.idleMicroPrompt && context.workItems.length === 0 && !isCommentOrderRunEarly) {
|
|
2674
2774
|
return buildIdleMicroPrompt(context);
|
|
2675
2775
|
}
|
|
2676
|
-
const
|
|
2776
|
+
const bootstrapPreamble = composeBootstrapPreamble(context);
|
|
2677
2777
|
const promptMode = resolveHeartbeatPromptModeForPrompt(context);
|
|
2678
2778
|
const isCompact = promptMode === "compact";
|
|
2679
2779
|
const memoryCap = resolveMemorySectionMaxChars(promptMode);
|
|
@@ -2696,6 +2796,11 @@ export function createPrompt(context: HeartbeatContext) {
|
|
|
2696
2796
|
`- [${item.issueId}] ${item.title}`,
|
|
2697
2797
|
` Project: ${item.projectName ?? item.projectId}`,
|
|
2698
2798
|
item.parentIssueId ? ` Parent issue: ${item.parentIssueId}` : null,
|
|
2799
|
+
...(item.goalAncestryChains && item.goalAncestryChains.length > 0
|
|
2800
|
+
? item.goalAncestryChains.map(
|
|
2801
|
+
(chain, idx) => ` Linked goal ${idx + 1} (root → leaf): ${chain.join(" → ")}`
|
|
2802
|
+
)
|
|
2803
|
+
: []),
|
|
2699
2804
|
item.childIssueIds?.length ? ` Sub-issues: ${item.childIssueIds.join(", ")}` : null,
|
|
2700
2805
|
item.status ? ` Status: ${item.status}` : null,
|
|
2701
2806
|
item.priority ? ` Priority: ${item.priority}` : null,
|
|
@@ -2785,6 +2890,8 @@ export function createPrompt(context: HeartbeatContext) {
|
|
|
2785
2890
|
: "- BOPODEV_REQUEST_HEADERS_JSON is missing. Report this as blocker."
|
|
2786
2891
|
].join("\n");
|
|
2787
2892
|
|
|
2893
|
+
const teamRosterBlock = formatTeamRosterSection(context);
|
|
2894
|
+
|
|
2788
2895
|
const executionDirectives = [
|
|
2789
2896
|
"Execution directives:",
|
|
2790
2897
|
"- You are running inside a BopoDev heartbeat for local repository work.",
|
|
@@ -2819,14 +2926,14 @@ export function createPrompt(context: HeartbeatContext) {
|
|
|
2819
2926
|
"- Do not invent token or cost values; the runtime records usage separately."
|
|
2820
2927
|
].join("\n");
|
|
2821
2928
|
|
|
2822
|
-
return `${
|
|
2929
|
+
return `${bootstrapPreamble}You are ${context.agent.name} (${context.agent.role}), agent ${context.agentId}.
|
|
2823
2930
|
Heartbeat run ${context.heartbeatRunId}.
|
|
2824
2931
|
${isCompact ? "Prompt profile: compact (issue bodies are not inlined—use GET /issues/:id to hydrate).\n" : ""}
|
|
2825
2932
|
Company:
|
|
2826
2933
|
- Name: ${context.company.name}
|
|
2827
2934
|
- Mission: ${context.company.mission ?? "No mission set"}
|
|
2828
2935
|
|
|
2829
|
-
Goal context:
|
|
2936
|
+
${teamRosterBlock}Goal context:
|
|
2830
2937
|
Company goals:
|
|
2831
2938
|
${companyGoals}
|
|
2832
2939
|
Project goals:
|
package/src/registry.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { dedupeModels } from "./adapters";
|
|
1
2
|
import type {
|
|
2
3
|
AdapterEnvironmentResult,
|
|
3
4
|
AdapterMetadata,
|
|
@@ -16,6 +17,7 @@ import { openaiapiAdapterModule } from "../../adapters/openai-api/src";
|
|
|
16
17
|
import { anthropicapiAdapterModule } from "../../adapters/anthropic-api/src";
|
|
17
18
|
import { httpAdapterModule } from "../../adapters/http/src";
|
|
18
19
|
import { shellAdapterModule } from "../../adapters/shell/src";
|
|
20
|
+
import { openclawGatewayAdapterModule } from "../../adapters/openclaw-gateway/src";
|
|
19
21
|
|
|
20
22
|
const adapterModules: Record<AgentProviderType, AdapterModule> = {
|
|
21
23
|
claude_code: claudecodeAdapterModule,
|
|
@@ -25,6 +27,7 @@ const adapterModules: Record<AgentProviderType, AdapterModule> = {
|
|
|
25
27
|
gemini_cli: geminiCliAdapterModule,
|
|
26
28
|
openai_api: openaiapiAdapterModule,
|
|
27
29
|
anthropic_api: anthropicapiAdapterModule,
|
|
30
|
+
openclaw_gateway: openclawGatewayAdapterModule,
|
|
28
31
|
http: httpAdapterModule,
|
|
29
32
|
shell: shellAdapterModule
|
|
30
33
|
};
|
|
@@ -62,6 +65,10 @@ const adapters: Record<AgentProviderType, AgentAdapter> = {
|
|
|
62
65
|
providerType: "anthropic_api",
|
|
63
66
|
execute: (context) => adapterModules.anthropic_api.server.execute(context)
|
|
64
67
|
},
|
|
68
|
+
openclaw_gateway: {
|
|
69
|
+
providerType: "openclaw_gateway",
|
|
70
|
+
execute: (context) => adapterModules.openclaw_gateway.server.execute(context)
|
|
71
|
+
},
|
|
65
72
|
http: {
|
|
66
73
|
providerType: "http",
|
|
67
74
|
execute: (context) => adapterModules.http.server.execute(context)
|
|
@@ -80,11 +87,19 @@ export async function getAdapterModels(
|
|
|
80
87
|
providerType: AgentProviderType,
|
|
81
88
|
runtime?: AgentRuntimeConfig
|
|
82
89
|
): Promise<AdapterModelOption[]> {
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
90
|
+
const mod = adapterModules[providerType];
|
|
91
|
+
const staticModels: AdapterModelOption[] = mod.models ? [...mod.models] : [];
|
|
92
|
+
const listModels = mod.server.listModels;
|
|
93
|
+
if (!listModels) {
|
|
94
|
+
return staticModels;
|
|
95
|
+
}
|
|
96
|
+
const discovered = await listModels(runtime);
|
|
97
|
+
const disc = Array.isArray(discovered) ? discovered : [];
|
|
98
|
+
if (disc.length > 0) {
|
|
99
|
+
return dedupeModels([...disc, ...staticModels]);
|
|
86
100
|
}
|
|
87
|
-
|
|
101
|
+
// Empty discovery (CLI missing, auth, timeout): keep static catalog so UIs are not stuck on client-only allowlists.
|
|
102
|
+
return staticModels.length > 0 ? staticModels : disc;
|
|
88
103
|
}
|
|
89
104
|
|
|
90
105
|
export function getAdapterMetadata(): AdapterMetadata[] {
|
package/src/types.ts
CHANGED
|
@@ -6,6 +6,10 @@ export interface AgentWorkItem {
|
|
|
6
6
|
issueId: string;
|
|
7
7
|
projectId: string;
|
|
8
8
|
parentIssueId?: string | null;
|
|
9
|
+
/** Linked planning goals for this issue, if any. */
|
|
10
|
+
goalIds?: string[];
|
|
11
|
+
/** Root-to-leaf chain per linked goal (same order as goalIds). */
|
|
12
|
+
goalAncestryChains?: string[][];
|
|
9
13
|
childIssueIds?: string[];
|
|
10
14
|
projectName?: string | null;
|
|
11
15
|
title: string;
|
|
@@ -81,6 +85,15 @@ export interface HeartbeatContext {
|
|
|
81
85
|
commentBody?: string | null;
|
|
82
86
|
issueIds?: string[];
|
|
83
87
|
};
|
|
88
|
+
/** Company agents (non-terminated), sorted by name; used for delegation and task routing hints. */
|
|
89
|
+
teamRoster?: Array<{
|
|
90
|
+
id: string;
|
|
91
|
+
name: string;
|
|
92
|
+
role: string;
|
|
93
|
+
title?: string | null;
|
|
94
|
+
capabilities?: string | null;
|
|
95
|
+
status: string;
|
|
96
|
+
}>;
|
|
84
97
|
}
|
|
85
98
|
|
|
86
99
|
/**
|