bopodev-agent-sdk 0.1.25 → 0.1.27

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.
Files changed (43) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-typecheck.log +1 -1
  3. package/README.md +27 -0
  4. package/dist/adapters/codex/src/server/quota.d.ts +2 -0
  5. package/dist/agent-sdk/src/adapters.d.ts +12 -1
  6. package/dist/agent-sdk/src/provider-failures/anthropic-api.d.ts +5 -0
  7. package/dist/agent-sdk/src/provider-failures/claude-code.d.ts +5 -0
  8. package/dist/agent-sdk/src/provider-failures/codex.d.ts +5 -0
  9. package/dist/agent-sdk/src/provider-failures/common.d.ts +7 -0
  10. package/dist/agent-sdk/src/provider-failures/cursor.d.ts +5 -0
  11. package/dist/agent-sdk/src/provider-failures/gemini-cli.d.ts +5 -0
  12. package/dist/agent-sdk/src/provider-failures/http.d.ts +5 -0
  13. package/dist/agent-sdk/src/provider-failures/index.d.ts +5 -0
  14. package/dist/agent-sdk/src/provider-failures/openai-api.d.ts +5 -0
  15. package/dist/agent-sdk/src/provider-failures/opencode.d.ts +5 -0
  16. package/dist/agent-sdk/src/provider-failures/shell.d.ts +5 -0
  17. package/dist/agent-sdk/src/provider-failures/types.d.ts +20 -0
  18. package/dist/agent-sdk/src/quota.d.ts +4 -0
  19. package/dist/agent-sdk/src/runtime-core.d.ts +1 -1
  20. package/dist/agent-sdk/src/runtime-http.d.ts +4 -2
  21. package/dist/agent-sdk/src/runtime-parsers.d.ts +1 -1
  22. package/dist/agent-sdk/src/runtime.d.ts +13 -0
  23. package/dist/agent-sdk/src/types.d.ts +19 -1
  24. package/dist/contracts/src/index.d.ts +426 -11
  25. package/package.json +2 -2
  26. package/src/adapters.ts +477 -58
  27. package/src/provider-failures/anthropic-api.ts +20 -0
  28. package/src/provider-failures/claude-code.ts +20 -0
  29. package/src/provider-failures/codex.ts +23 -0
  30. package/src/provider-failures/common.ts +86 -0
  31. package/src/provider-failures/cursor.ts +20 -0
  32. package/src/provider-failures/gemini-cli.ts +20 -0
  33. package/src/provider-failures/http.ts +12 -0
  34. package/src/provider-failures/index.ts +54 -0
  35. package/src/provider-failures/openai-api.ts +20 -0
  36. package/src/provider-failures/opencode.ts +20 -0
  37. package/src/provider-failures/shell.ts +12 -0
  38. package/src/provider-failures/types.ts +28 -0
  39. package/src/runtime-core.ts +7 -1
  40. package/src/runtime-http.ts +51 -6
  41. package/src/runtime-parsers.ts +1 -0
  42. package/src/runtime.ts +299 -1
  43. package/src/types.ts +20 -1
@@ -1,5 +1,5 @@
1
1
 
2
2
  
3
- > bopodev-agent-sdk@0.1.25 build /Users/danielkrusenstrahle/Documents/Projects/Monorepo/bopohq/packages/agent-sdk
3
+ > bopodev-agent-sdk@0.1.27 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.24 typecheck /Users/danielkrusenstrahle/Documents/Projects/Monorepo/bopohq/packages/agent-sdk
2
+ > bopodev-agent-sdk@0.1.26 typecheck /Users/danielkrusenstrahle/Documents/Projects/Monorepo/bopohq/packages/agent-sdk
3
3
  > tsc -p tsconfig.json --noEmit
4
4
 
package/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # `packages/agent-sdk`
2
+
3
+ Runtime orchestration SDK for adapter resolution, execution integration, and runtime health checks.
4
+
5
+ ## Responsibilities
6
+
7
+ - Resolve and register adapter modules.
8
+ - Provide shared execution/runtime helpers used by API heartbeat workflows.
9
+ - Expose runtime command health checks used at API startup and health endpoints.
10
+
11
+ ## Usage
12
+
13
+ Primary consumers:
14
+
15
+ - `apps/api` heartbeat and startup paths.
16
+ - `packages/adapters/*` through adapter module contracts.
17
+
18
+ ## Commands
19
+
20
+ - `pnpm --filter bopodev-agent-sdk build`
21
+ - `pnpm --filter bopodev-agent-sdk typecheck`
22
+
23
+ ## Related Docs
24
+
25
+ - `docs/adapters/overview.md`
26
+ - `docs/adapter-authoring.md`
27
+ - `docs/developer/architecture.md`
@@ -0,0 +1,2 @@
1
+ import type { AgentRuntimeConfig, AdapterQuotaProbeResult } from "../../../../agent-sdk/src/types";
2
+ export declare function probeQuota(runtime?: AgentRuntimeConfig): Promise<AdapterQuotaProbeResult>;
@@ -1,5 +1,13 @@
1
1
  import type { AdapterEnvironmentCheck, AdapterEnvironmentResult, AdapterExecutionResult, AdapterMetadata, AdapterModelOption, AdapterNormalizedUsage, AgentAdapter, AgentProviderType, AgentRuntimeConfig, HeartbeatContext } from "./types";
2
2
  import { type DirectApiProvider } from "./runtime-http";
3
+ import { classifyProviderFailure as classifyProviderFailureByProvider } from "./provider-failures";
4
+ export declare function normalizeProviderFailureDetail(provider: AgentProviderType, detail: string): string;
5
+ export declare function classifyProviderFailure(provider: AgentProviderType, input: {
6
+ detail: string;
7
+ stderr?: string;
8
+ stdout?: string;
9
+ failureType?: string | null;
10
+ }): ReturnType<typeof classifyProviderFailureByProvider>;
3
11
  type RuntimeParsedUsage = {
4
12
  tokenInput?: number;
5
13
  tokenOutput?: number;
@@ -114,6 +122,7 @@ export declare function toProviderResult(context: HeartbeatContext, provider: Ag
114
122
  forcedKill: boolean;
115
123
  }>;
116
124
  parsedUsage?: RuntimeParsedUsage;
125
+ finalRunOutput?: AdapterExecutionResult["finalRunOutput"];
117
126
  structuredOutputSource?: "stdout" | "stderr";
118
127
  structuredOutputDiagnostics?: {
119
128
  stdoutJsonObjectCount: number;
@@ -125,6 +134,8 @@ export declare function toProviderResult(context: HeartbeatContext, provider: Ag
125
134
  lastStdoutLine?: string;
126
135
  lastStderrLine?: string;
127
136
  likelyCause: "no_output_from_runtime" | "json_missing" | "json_on_stderr_only" | "schema_or_shape_mismatch";
137
+ finalRunOutputStatus?: "valid" | "missing" | "malformed" | "schema_mismatch";
138
+ finalRunOutputError?: string;
128
139
  claudeStopReason?: string;
129
140
  claudeResultSubtype?: string;
130
141
  claudeSessionId?: string;
@@ -165,7 +176,7 @@ export declare function resolveRuntimeFailureDetail(runtime: {
165
176
  attempts: Array<{
166
177
  spawnErrorCode?: string;
167
178
  }>;
168
- }): string;
179
+ }, provider?: AgentProviderType): string;
169
180
  export declare function parseOpenCodeOutput(stdout: string): {
170
181
  sessionId: string | null;
171
182
  };
@@ -0,0 +1,5 @@
1
+ import type { ProviderFailureNormalizer } from "./types";
2
+ export declare const anthropicApiFailureResolver: {
3
+ normalize: ProviderFailureNormalizer;
4
+ classify: import("./types").ProviderFailureClassifier;
5
+ };
@@ -0,0 +1,5 @@
1
+ import type { ProviderFailureNormalizer } from "./types";
2
+ export declare const claudeCodeFailureResolver: {
3
+ normalize: ProviderFailureNormalizer;
4
+ classify: import("./types").ProviderFailureClassifier;
5
+ };
@@ -0,0 +1,5 @@
1
+ import type { ProviderFailureNormalizer } from "./types";
2
+ export declare const codexFailureResolver: {
3
+ normalize: ProviderFailureNormalizer;
4
+ classify: import("./types").ProviderFailureClassifier;
5
+ };
@@ -0,0 +1,7 @@
1
+ import type { ProviderFailureClassification, ProviderFailureClassifier, ProviderFailureInput, ProviderFailureNormalizer } from "./types";
2
+ export declare function normalizeWhitespace(value: string): string;
3
+ export declare function hasModelUnsupportedSignal(haystack: string): boolean;
4
+ export declare function hasAuthFailureSignal(haystack: string): boolean;
5
+ export declare function hasUnknownSessionSignal(haystack: string): boolean;
6
+ export declare function classifyFromSignals(normalize: ProviderFailureNormalizer, input: ProviderFailureInput): ProviderFailureClassification;
7
+ export declare function createClassifier(normalize: ProviderFailureNormalizer): ProviderFailureClassifier;
@@ -0,0 +1,5 @@
1
+ import type { ProviderFailureNormalizer } from "./types";
2
+ export declare const cursorFailureResolver: {
3
+ normalize: ProviderFailureNormalizer;
4
+ classify: import("./types").ProviderFailureClassifier;
5
+ };
@@ -0,0 +1,5 @@
1
+ import type { ProviderFailureNormalizer } from "./types";
2
+ export declare const geminiCliFailureResolver: {
3
+ normalize: ProviderFailureNormalizer;
4
+ classify: import("./types").ProviderFailureClassifier;
5
+ };
@@ -0,0 +1,5 @@
1
+ import type { ProviderFailureNormalizer } from "./types";
2
+ export declare const httpFailureResolver: {
3
+ normalize: ProviderFailureNormalizer;
4
+ classify: import("./types").ProviderFailureClassifier;
5
+ };
@@ -0,0 +1,5 @@
1
+ import type { AgentProviderType } from "../types";
2
+ import type { ProviderFailureClassification, ProviderFailureInput } from "./types";
3
+ export declare function normalizeProviderFailureDetail(provider: AgentProviderType, detail: string): string;
4
+ export declare function classifyProviderFailure(provider: AgentProviderType, input: ProviderFailureInput): ProviderFailureClassification;
5
+ export type { ProviderFailureClassification, ProviderFailureInput } from "./types";
@@ -0,0 +1,5 @@
1
+ import type { ProviderFailureNormalizer } from "./types";
2
+ export declare const openAiApiFailureResolver: {
3
+ normalize: ProviderFailureNormalizer;
4
+ classify: import("./types").ProviderFailureClassifier;
5
+ };
@@ -0,0 +1,5 @@
1
+ import type { ProviderFailureNormalizer } from "./types";
2
+ export declare const opencodeFailureResolver: {
3
+ normalize: ProviderFailureNormalizer;
4
+ classify: import("./types").ProviderFailureClassifier;
5
+ };
@@ -0,0 +1,5 @@
1
+ import type { ProviderFailureNormalizer } from "./types";
2
+ export declare const shellFailureResolver: {
3
+ normalize: ProviderFailureNormalizer;
4
+ classify: import("./types").ProviderFailureClassifier;
5
+ };
@@ -0,0 +1,20 @@
1
+ import type { AgentProviderType } from "../types";
2
+ export type ProviderFailureInput = {
3
+ detail: string;
4
+ stderr?: string;
5
+ stdout?: string;
6
+ failureType?: string | null;
7
+ };
8
+ export type ProviderFailureClassification = {
9
+ detail: string;
10
+ blockerCode: string;
11
+ retryable: boolean;
12
+ providerUsageLimited: boolean;
13
+ };
14
+ export type ProviderFailureClassifier = (input: ProviderFailureInput) => ProviderFailureClassification;
15
+ export type ProviderFailureNormalizer = (detail: string) => string;
16
+ export type ProviderFailureResolver = {
17
+ normalize: ProviderFailureNormalizer;
18
+ classify: ProviderFailureClassifier;
19
+ };
20
+ export type ProviderFailureResolverMap = Partial<Record<AgentProviderType, ProviderFailureResolver>>;
@@ -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;
@@ -1,2 +1,2 @@
1
1
  export type { RuntimeAttemptTrace, RuntimeCommandHealth, RuntimeExecutionOutput, RuntimeTranscriptEvent } from "./runtime";
2
- export { checkRuntimeCommandHealth, containsRateLimitFailure, executeAgentRuntime, executePromptRuntime } from "./runtime";
2
+ export { checkRuntimeCommandHealth, containsUsageLimitHardStopFailure, containsRateLimitFailure, executeAgentRuntime, executePromptRuntime } from "./runtime";
@@ -1,4 +1,5 @@
1
1
  import type { AgentRuntimeConfig } from "./types";
2
+ import type { AgentFinalRunOutput } from "bopodev-contracts";
2
3
  export type DirectApiProvider = "openai_api" | "anthropic_api";
3
4
  export type DirectApiExecutionOutput = {
4
5
  ok: boolean;
@@ -8,10 +9,11 @@ export type DirectApiExecutionOutput = {
8
9
  elapsedMs: number;
9
10
  statusCode: number;
10
11
  summary?: string;
12
+ finalRunOutput?: AgentFinalRunOutput;
11
13
  tokenInput?: number;
12
14
  tokenOutput?: number;
13
15
  usdCost?: number;
14
- failureType?: "auth" | "rate_limit" | "timeout" | "network" | "bad_response" | "http_error";
16
+ failureType?: "auth" | "rate_limit" | "out_of_funds" | "quota_exhausted" | "timeout" | "network" | "bad_response" | "http_error";
15
17
  error?: string;
16
18
  responsePreview?: string;
17
19
  attemptCount: number;
@@ -19,7 +21,7 @@ export type DirectApiExecutionOutput = {
19
21
  attempt: number;
20
22
  statusCode: number;
21
23
  elapsedMs: number;
22
- failureType?: "auth" | "rate_limit" | "timeout" | "network" | "bad_response" | "http_error";
24
+ failureType?: "auth" | "rate_limit" | "out_of_funds" | "quota_exhausted" | "timeout" | "network" | "bad_response" | "http_error";
23
25
  error?: string;
24
26
  }>;
25
27
  };
@@ -1 +1 @@
1
- export { parseClaudeStreamOutput, parseCursorStreamOutput, parseGeminiStreamOutput, parseRuntimeTranscript, parseStructuredUsage } from "./runtime";
1
+ export { parseAgentFinalRunOutput, parseClaudeStreamOutput, parseCursorStreamOutput, parseGeminiStreamOutput, parseRuntimeTranscript, parseStructuredUsage } from "./runtime";
@@ -1,3 +1,4 @@
1
+ import { type AgentFinalRunOutput } from "bopodev-contracts";
1
2
  import type { AgentRuntimeConfig } from "./types";
2
3
  type LocalProvider = "claude_code" | "codex" | "cursor" | "opencode" | "gemini_cli";
3
4
  type ClaudeContractDiagnostics = {
@@ -19,6 +20,7 @@ type ParsedUsageRecord = {
19
20
  usdCost?: number;
20
21
  summary?: string;
21
22
  };
23
+ type FinalRunOutputParseError = "missing" | "malformed" | "schema_mismatch";
22
24
  type CursorParsedStream = {
23
25
  usage: ParsedUsageRecord;
24
26
  sessionId?: string;
@@ -43,6 +45,8 @@ export interface RuntimeExecutionOutput {
43
45
  usdCost?: number;
44
46
  summary?: string;
45
47
  };
48
+ finalRunOutput?: AgentFinalRunOutput;
49
+ finalRunOutputSource?: "stdout" | "stderr";
46
50
  structuredOutputSource?: "stdout" | "stderr";
47
51
  structuredOutputDiagnostics?: {
48
52
  stdoutJsonObjectCount: number;
@@ -54,6 +58,8 @@ export interface RuntimeExecutionOutput {
54
58
  lastStdoutLine?: string;
55
59
  lastStderrLine?: string;
56
60
  likelyCause: "no_output_from_runtime" | "json_missing" | "json_on_stderr_only" | "schema_or_shape_mismatch";
61
+ finalRunOutputStatus?: "valid" | "missing" | "malformed" | "schema_mismatch";
62
+ finalRunOutputError?: string;
57
63
  claudeStopReason?: string;
58
64
  claudeResultSubtype?: string;
59
65
  claudeSessionId?: string;
@@ -94,6 +100,8 @@ export declare function executePromptRuntime(command: string, prompt: string, co
94
100
  claudeContract?: ClaudeContractDiagnostics;
95
101
  }): Promise<RuntimeExecutionOutput>;
96
102
  export declare function containsRateLimitFailure(text: string): boolean;
103
+ export declare function containsUsageLimitHardStopFailure(text: string): boolean;
104
+ export declare function containsProviderUsageLimitFailure(text: string): boolean;
97
105
  export declare function checkRuntimeCommandHealth(command: string, options?: {
98
106
  cwd?: string;
99
107
  timeoutMs?: number;
@@ -117,4 +125,9 @@ export declare function parseGeminiStreamOutput(stdout: string, stderr?: string)
117
125
  sessionId?: string;
118
126
  } | undefined;
119
127
  export declare function parseRuntimeTranscript(provider: LocalProvider | undefined, stdout: string, stderr: string): RuntimeTranscriptEvent[] | undefined;
128
+ export declare function parseAgentFinalRunOutput(text: string): {
129
+ output?: AgentFinalRunOutput;
130
+ error?: FinalRunOutputParseError;
131
+ detail?: string;
132
+ };
120
133
  export {};
@@ -1,4 +1,4 @@
1
- import type { ExecutionOutcome, ProviderType } from "bopodev-contracts";
1
+ import type { AgentFinalRunOutput, ExecutionOutcome, ProviderType } from "bopodev-contracts";
2
2
  export type AgentProviderType = ProviderType;
3
3
  export interface AgentWorkItem {
4
4
  issueId: string;
@@ -19,6 +19,8 @@ export interface AgentWorkItem {
19
19
  fileSizeBytes: number;
20
20
  relativePath: string;
21
21
  absolutePath: string;
22
+ /** API-relative path, e.g. `/issues/{issueId}/attachments/{id}/download` */
23
+ downloadPath?: string;
22
24
  }>;
23
25
  }
24
26
  export interface AgentState {
@@ -36,11 +38,19 @@ export interface AgentMemoryContext {
36
38
  durableFacts: string[];
37
39
  dailyNotes: string[];
38
40
  }
41
+ export type HeartbeatPromptMode = "full" | "compact";
39
42
  export interface HeartbeatContext {
40
43
  companyId: string;
41
44
  agentId: string;
42
45
  providerType: AgentProviderType;
43
46
  heartbeatRunId: string;
47
+ /** Controls how much issue/memory text is inlined in the heartbeat prompt. Default when omitted: full. */
48
+ promptMode?: HeartbeatPromptMode;
49
+ /**
50
+ * When true, emit a minimal idle prompt (no assigned work). Set by the API when
51
+ * `BOPO_HEARTBEAT_IDLE_POLICY=micro_prompt` and there are no work items.
52
+ */
53
+ idleMicroPrompt?: boolean;
44
54
  company: {
45
55
  name: string;
46
56
  mission?: string | null;
@@ -88,12 +98,20 @@ export interface AdapterExecutionResult {
88
98
  tokenInput: number;
89
99
  tokenOutput: number;
90
100
  usdCost: number;
101
+ finalRunOutput?: AgentFinalRunOutput;
91
102
  usage?: AdapterNormalizedUsage;
92
103
  pricingProviderType?: string | null;
93
104
  pricingModelId?: string | null;
94
105
  outcome?: ExecutionOutcome;
95
106
  nextState?: AgentState;
96
107
  trace?: AdapterTrace;
108
+ dispositionHint?: {
109
+ kind: "provider_usage_limited";
110
+ persistStatus: "skipped";
111
+ pauseAgent: boolean;
112
+ notifyBoard: boolean;
113
+ message: string;
114
+ };
97
115
  }
98
116
  export interface AgentAdapter {
99
117
  providerType: AgentProviderType;