@obversa/engine-devin-cli 0.1.0 → 0.1.1
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/README.md +4 -2
- package/dist/devin-cli.d.ts +16 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +18 -4
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -22,9 +22,11 @@ import { devin } from '@obversa/engine-devin-cli';
|
|
|
22
22
|
const seat = devin('swe-2-max');
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
Without a model,
|
|
25
|
+
Without a model, Devin runs its own default model, or the one your Devin settings choose with `clean: false`.
|
|
26
26
|
|
|
27
|
-
Devin runs with your own environment
|
|
27
|
+
Devin runs clean by default: with your own environment and Devin login,
|
|
28
|
+
but with an empty config file in place of your Devin settings. Set
|
|
29
|
+
`clean: false` to run with your Devin settings too. A
|
|
28
30
|
read-only step runs with `--permission-mode auto`, and a step that may write
|
|
29
31
|
runs with `--permission-mode accept-edits`. Devin has no mode without a
|
|
30
32
|
folder and no flag for a list of named tools. The plugin passes
|
package/dist/devin-cli.d.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import { type AgentRequest, type AgentResult, type Engine, type EngineEventSink, type EngineSelectionRecord } from '@obversa/api';
|
|
2
2
|
export interface DevinCliEngineOptions {
|
|
3
|
-
/** Model for requests that name none. Without
|
|
3
|
+
/** Model for requests that name none. Without a model, Devin runs its own default model, or the one your Devin settings choose with `clean: false`. */
|
|
4
4
|
readonly defaultModel?: string;
|
|
5
5
|
/** Absolute path or bare command name; `devin` by default. */
|
|
6
6
|
readonly cliBinary?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Run with an empty Devin config file in place of the person's own
|
|
9
|
+
* `~/.config/devin/config.json`. Their own MCP servers and skills still
|
|
10
|
+
* load, because Devin has no switch to leave them out. The repository's
|
|
11
|
+
* instruction files still apply, and the run keeps the person's login.
|
|
12
|
+
* On by default; `false` runs on the person's own setup.
|
|
13
|
+
*/
|
|
14
|
+
readonly clean?: boolean;
|
|
7
15
|
}
|
|
8
16
|
export interface DevinSeat {
|
|
9
17
|
readonly engine: DevinCliEngine;
|
|
@@ -15,12 +23,15 @@ export interface DevinSeat {
|
|
|
15
23
|
readonly tools: readonly string[];
|
|
16
24
|
};
|
|
17
25
|
}
|
|
26
|
+
export interface DevinSeatOptions {
|
|
27
|
+
readonly clean?: boolean;
|
|
28
|
+
}
|
|
18
29
|
/**
|
|
19
30
|
* Create the Devin seat used by declarative team workflows. Without a model,
|
|
20
|
-
* Devin runs
|
|
21
|
-
* seat records the model as `default`.
|
|
31
|
+
* Devin runs its own default model, or the one your Devin settings choose with
|
|
32
|
+
* `clean: false`, and the seat records the model as `default`.
|
|
22
33
|
*/
|
|
23
|
-
export declare function devin(model?: string): DevinSeat;
|
|
34
|
+
export declare function devin(model?: string, options?: DevinSeatOptions): DevinSeat;
|
|
24
35
|
/**
|
|
25
36
|
* Build the `devin` argv for one attempt. Exported so the flag wiring is
|
|
26
37
|
* testable without spawning a process.
|
|
@@ -28,6 +39,7 @@ export declare function devin(model?: string): DevinSeat;
|
|
|
28
39
|
export declare function buildDevinArgs(req: AgentRequest, opts: DevinCliEngineOptions, files: {
|
|
29
40
|
readonly promptFile: string;
|
|
30
41
|
readonly exportFile: string;
|
|
42
|
+
readonly configFile?: string;
|
|
31
43
|
}): string[];
|
|
32
44
|
export declare class DevinCliEngine implements Engine {
|
|
33
45
|
private readonly opts;
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { DevinCliEngine, devin, buildDevinArgs, type DevinSeat, type DevinCliEngineOptions, } from './devin-cli.js';
|
|
1
|
+
export { DevinCliEngine, devin, buildDevinArgs, type DevinSeat, type DevinSeatOptions, type DevinCliEngineOptions, } from './devin-cli.js';
|
package/dist/index.js
CHANGED
|
@@ -90,10 +90,15 @@ var ADAPTER = "devin-cli";
|
|
|
90
90
|
var PROVIDER = "cognition";
|
|
91
91
|
var DEFAULT_MODEL = "default";
|
|
92
92
|
var DIAGNOSTIC_MAX = 700;
|
|
93
|
-
|
|
93
|
+
var CLEAN_BY_DEFAULT = true;
|
|
94
|
+
var CLEAN_CONFIG = "{}\n";
|
|
95
|
+
function devin(model, options = {}) {
|
|
94
96
|
if (model !== void 0 && !model.trim()) throw new TypeError("devin model must not be empty");
|
|
95
97
|
return {
|
|
96
|
-
engine: new DevinCliEngine(
|
|
98
|
+
engine: new DevinCliEngine({
|
|
99
|
+
...model === void 0 ? {} : { defaultModel: model },
|
|
100
|
+
...options.clean === void 0 ? {} : { clean: options.clean }
|
|
101
|
+
}),
|
|
97
102
|
identity: {
|
|
98
103
|
adapter: ADAPTER,
|
|
99
104
|
provider: PROVIDER,
|
|
@@ -111,8 +116,12 @@ function permissionMode(req) {
|
|
|
111
116
|
return req.workspaceMode === "write" ? "accept-edits" : "auto";
|
|
112
117
|
}
|
|
113
118
|
function buildDevinArgs(req, opts, files) {
|
|
119
|
+
const clean = opts.clean ?? CLEAN_BY_DEFAULT;
|
|
114
120
|
try {
|
|
115
121
|
assertReadAccess(req);
|
|
122
|
+
if (clean && files.configFile === void 0) {
|
|
123
|
+
throw new TypeError("devin clean mode requires an empty config file");
|
|
124
|
+
}
|
|
116
125
|
if (req.tools?.length === 0) {
|
|
117
126
|
throw new TypeError("devin cannot turn its tools off; choose an engine that supports tools: []");
|
|
118
127
|
}
|
|
@@ -139,6 +148,7 @@ function buildDevinArgs(req, opts, files) {
|
|
|
139
148
|
// every folder the person has not opened in Devin before refuses to run.
|
|
140
149
|
"--respect-workspace-trust",
|
|
141
150
|
"false",
|
|
151
|
+
...clean ? ["--config", files.configFile] : [],
|
|
142
152
|
...model === void 0 ? [] : ["--model", model]
|
|
143
153
|
];
|
|
144
154
|
}
|
|
@@ -153,7 +163,7 @@ function requestedSelection(req, opts) {
|
|
|
153
163
|
});
|
|
154
164
|
}
|
|
155
165
|
function assertDevinConfiguration(req, opts) {
|
|
156
|
-
buildDevinArgs(req, opts, { promptFile: "prompt", exportFile: "export" });
|
|
166
|
+
buildDevinArgs(req, opts, { promptFile: "prompt", exportFile: "export", configFile: "config" });
|
|
157
167
|
try {
|
|
158
168
|
const env = attemptEnvironment(req) ?? {};
|
|
159
169
|
const limits = {
|
|
@@ -311,6 +321,7 @@ var DevinCliEngine = class {
|
|
|
311
321
|
const dir = mkdtempSync(join(tmpdir(), "obversa-devin-"));
|
|
312
322
|
const promptFile = join(dir, "prompt.md");
|
|
313
323
|
const exportFile = join(dir, "conversation.json");
|
|
324
|
+
const configFile = join(dir, "config.json");
|
|
314
325
|
const env = attemptEnvironment(req);
|
|
315
326
|
try {
|
|
316
327
|
writeFileSync(
|
|
@@ -322,9 +333,12 @@ var DevinCliEngine = class {
|
|
|
322
333
|
${req.prompt}` : req.prompt,
|
|
323
334
|
{ encoding: "utf8", mode: 384 }
|
|
324
335
|
);
|
|
336
|
+
if (this.opts.clean ?? CLEAN_BY_DEFAULT) {
|
|
337
|
+
writeFileSync(configFile, CLEAN_CONFIG, { encoding: "utf8", mode: 384 });
|
|
338
|
+
}
|
|
325
339
|
const sub = await runOwnedCommand({
|
|
326
340
|
executable,
|
|
327
|
-
args: buildDevinArgs(req, this.opts, { promptFile, exportFile }),
|
|
341
|
+
args: buildDevinArgs(req, this.opts, { promptFile, exportFile, configFile }),
|
|
328
342
|
cwd: req.cwd ?? process.cwd(),
|
|
329
343
|
env: env ?? {},
|
|
330
344
|
stdin: "",
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/atif.ts","../src/devin-cli.ts"],"names":["value"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Read the conversation file `devin --export` writes. Devin 3000.11 writes it\n * in the ATIF v1 shape: ordered steps from the system, the user and the agent,\n * with each agent step carrying its text, its tool calls, the results of those\n * calls and the model that produced it.\n */\nimport type { EngineStreamEvent, UsageReceipt } from '@obversa/api';\n\nexport interface DevinConversation {\n /** Every non-empty agent message, in order. */\n readonly messages: readonly string[];\n /** True when the conversation ends on an agent message with no tool calls. */\n readonly answered: boolean;\n /** The model named on the last agent step, when Devin names one. */\n readonly model: string | undefined;\n readonly toolEvents: readonly Extract<EngineStreamEvent, { type: 'tool' }>[];\n readonly usage: UsageReceipt;\n}\n\nfunction record(value: unknown, what: string): Record<string, unknown> {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(`Devin export ${what} is not an object`);\n }\n return value as Record<string, unknown>;\n}\n\nfunction messageText(value: unknown): string {\n if (typeof value === 'string') return value;\n if (!Array.isArray(value)) return '';\n return value\n .map((part) => (part !== null && typeof part === 'object'\n && (part as Record<string, unknown>).type === 'text'\n && typeof (part as Record<string, unknown>).text === 'string'\n ? (part as Record<string, string>).text\n : ''))\n .join('');\n}\n\nfunction tokenCount(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;\n}\n\nfunction usage(value: unknown): UsageReceipt {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n return { kind: 'unknown' };\n }\n const totals = value as Record<string, unknown>;\n const input = totals.total_prompt_tokens;\n const output = totals.total_completion_tokens;\n const cached = totals.total_cached_tokens;\n if (!tokenCount(input) || !tokenCount(output)\n || (cached != null && (!tokenCount(cached) || cached > input))) {\n return { kind: 'unknown' };\n }\n return {\n kind: 'reported',\n inputTokens: input,\n outputTokens: output,\n ...(cached == null ? {} : { cacheReadInputTokens: cached }),\n };\n}\n\nexport function readDevinExport(value: unknown): DevinConversation {\n const root = record(value, 'root');\n if (typeof root.schema_version !== 'string' || !root.schema_version.startsWith('ATIF-v1.')) {\n throw new Error('Devin export is not in the ATIF v1 shape');\n }\n if (!Array.isArray(root.steps)) throw new Error('Devin export has no steps');\n\n const messages: string[] = [];\n const toolEvents: Extract<EngineStreamEvent, { type: 'tool' }>[] = [];\n let answered = false;\n let model: string | undefined;\n for (const value of root.steps) {\n const step = record(value, 'step');\n if (step.source !== 'agent') {\n answered = false;\n continue;\n }\n if (typeof step.model_name === 'string' && step.model_name.length > 0) {\n model = step.model_name;\n }\n const calls = new Map<string, string>();\n if (Array.isArray(step.tool_calls)) {\n for (const value of step.tool_calls) {\n const call = record(value, 'tool call');\n if (typeof call.tool_call_id !== 'string' || typeof call.function_name !== 'string') {\n throw new Error('Devin export has a tool call without an id or a name');\n }\n calls.set(call.tool_call_id, call.function_name);\n toolEvents.push({ type: 'tool', name: call.function_name, phase: 'use' });\n }\n }\n const results = step.observation === undefined || step.observation === null\n ? []\n : record(step.observation, 'observation').results;\n if (Array.isArray(results)) {\n for (const value of results) {\n const id = record(value, 'tool result').source_call_id;\n const name = typeof id === 'string' ? calls.get(id) : undefined;\n if (name !== undefined) toolEvents.push({ type: 'tool', name, phase: 'result' });\n }\n }\n const text = messageText(step.message);\n if (text.length > 0) messages.push(text);\n answered = text.length > 0 && calls.size === 0;\n }\n return { messages, answered, model, toolEvents, usage: usage(root.final_metrics) };\n}\n","/**\n * Engine plugin: the `devin` CLI as a non-interactive subprocess. One fresh\n * `devin -p` process runs each attempt, with the person's own environment,\n * Devin login and Devin settings. The plugin adds only what the step needs:\n * Devin's permission mode for the workspace mode, the model when one is named,\n * and a conversation export it reads the answer from.\n */\nimport { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, isAbsolute, join } from 'node:path';\nimport { isDeepStrictEqual } from 'node:util';\nimport {\n EngineError,\n EngineIncompleteResultError,\n assertReadAccess,\n classifyEngineFailure,\n engineSelection,\n modelIdentity,\n validateAgentResult,\n type AgentRequest,\n type AgentResult,\n type AgentResultPart,\n type Engine,\n type EngineEventSink,\n type EngineSelectionRecord,\n} from '@obversa/api';\nimport {\n attemptEnvironment,\n scrubCapture,\n DEFAULT_OWNED_COMMAND_LIMITS,\n OwnedCommandError,\n ownedCommandIdentity,\n resolveCommandExecutable,\n runOwnedCommand,\n} from '@obversa/core/command';\nimport { readDevinExport, type DevinConversation } from './atif.js';\n\nconst ADAPTER = 'devin-cli';\nconst PROVIDER = 'cognition';\n/** The model a seat records when it leaves the choice to the person's Devin settings. */\nconst DEFAULT_MODEL = 'default';\nconst DIAGNOSTIC_MAX = 700;\n\nexport interface DevinCliEngineOptions {\n /** Model for requests that name none. Without one, Devin uses the person's default. */\n readonly defaultModel?: string;\n /** Absolute path or bare command name; `devin` by default. */\n readonly cliBinary?: string;\n}\n\nexport interface DevinSeat {\n readonly engine: DevinCliEngine;\n readonly identity: {\n readonly adapter: 'devin-cli';\n readonly provider: 'cognition';\n readonly modelFamily: string;\n readonly model: string;\n readonly tools: readonly string[];\n };\n}\n\n/**\n * Create the Devin seat used by declarative team workflows. Without a model,\n * Devin runs the default model from the person's own Devin settings and the\n * seat records the model as `default`.\n */\nexport function devin(model?: string): DevinSeat {\n if (model !== undefined && !model.trim()) throw new TypeError('devin model must not be empty');\n return {\n engine: new DevinCliEngine(model === undefined ? {} : { defaultModel: model }),\n identity: {\n adapter: ADAPTER,\n provider: PROVIDER,\n modelFamily: modelIdentity(model ?? DEFAULT_MODEL).modelFamily,\n model: model ?? DEFAULT_MODEL,\n tools: ['read', 'edit', 'exec'],\n },\n };\n}\n\nfunction modelFor(req: AgentRequest, opts: DevinCliEngineOptions): string | undefined {\n const model = req.model ?? opts.defaultModel;\n return model === undefined || model === DEFAULT_MODEL ? undefined : model;\n}\n\n/** Devin's permission mode for a workspace mode: read-only tools, or those plus workspace edits. */\nfunction permissionMode(req: AgentRequest): 'auto' | 'accept-edits' {\n return req.workspaceMode === 'write' ? 'accept-edits' : 'auto';\n}\n\n/**\n * Build the `devin` argv for one attempt. Exported so the flag wiring is\n * testable without spawning a process.\n */\nexport function buildDevinArgs(\n req: AgentRequest,\n opts: DevinCliEngineOptions,\n files: { readonly promptFile: string; readonly exportFile: string },\n): string[] {\n try {\n assertReadAccess(req);\n if (req.tools?.length === 0) {\n throw new TypeError('devin cannot turn its tools off; choose an engine that supports tools: []');\n }\n if (req.workspaceMode === 'none') {\n throw new TypeError('devin has no mode without workspace access; choose read or write');\n }\n } catch (cause) {\n throw new EngineError({\n kind: 'invalid-config',\n message: cause instanceof Error ? cause.message : 'invalid Devin workspace configuration',\n cause,\n });\n }\n const model = modelFor(req, opts);\n return [\n '-p',\n '--prompt-file', files.promptFile,\n '--export', files.exportFile,\n '--permission-mode', permissionMode(req),\n // Print mode cannot show Devin's folder trust prompt; without this flag\n // every folder the person has not opened in Devin before refuses to run.\n '--respect-workspace-trust', 'false',\n ...(model === undefined ? [] : ['--model', model]),\n ];\n}\n\nfunction requestedSelection(req: AgentRequest, opts: DevinCliEngineOptions): EngineSelectionRecord {\n const model = modelFor(req, opts);\n return engineSelection({\n adapter: ADAPTER,\n provider: PROVIDER,\n modelFamily: model === undefined ? null : modelIdentity(model).modelFamily,\n model: model ?? null,\n capabilities: req.tools ?? [],\n });\n}\n\nfunction assertDevinConfiguration(req: AgentRequest, opts: DevinCliEngineOptions): void {\n buildDevinArgs(req, opts, { promptFile: 'prompt', exportFile: 'export' });\n try {\n const env = attemptEnvironment(req) ?? {};\n const limits = {\n timeoutMs: req.timeoutMs ?? DEFAULT_OWNED_COMMAND_LIMITS.timeoutMs,\n teardownGraceMs: req.timeoutGraceMs ?? DEFAULT_OWNED_COMMAND_LIMITS.teardownGraceMs,\n maxOutputBytes: req.maxOutputBytes ?? DEFAULT_OWNED_COMMAND_LIMITS.maxOutputBytes,\n maxMemoryBytes: req.maxMemoryBytes ?? DEFAULT_OWNED_COMMAND_LIMITS.maxMemoryBytes,\n };\n if (!isAbsolute(req.cwd ?? process.cwd())\n || Object.values(env).some((value) => typeof value !== 'string')\n || !Number.isSafeInteger(limits.timeoutMs) || limits.timeoutMs < 1\n || !Number.isSafeInteger(limits.teardownGraceMs) || limits.teardownGraceMs < 0\n || limits.timeoutMs + limits.teardownGraceMs > 2_147_483_647\n || !Number.isSafeInteger(limits.maxOutputBytes) || limits.maxOutputBytes < 0\n || !Number.isSafeInteger(limits.maxMemoryBytes) || limits.maxMemoryBytes < 1) {\n throw new Error('invalid Devin command request');\n }\n ownedCommandIdentity({ adapter: ADAPTER, runId: req.attempt?.runId,\n leafId: req.attempt?.leafId, attemptId: req.attempt?.attemptId });\n } catch {\n throw new EngineError({ kind: 'invalid-config', message: 'invalid Devin command configuration' });\n }\n}\n\nfunction devinCommandError(error: unknown, executable?: string): unknown {\n if (!(error instanceof OwnedCommandError)) return error;\n if (error.code === 'INVALID_EXECUTABLE') {\n return new EngineError({ kind: 'missing-cli', message: 'Devin executable is not runnable' });\n }\n if (error.code === 'INVALID_COMMAND') {\n return new EngineError({ kind: 'invalid-config', message: 'invalid Devin command request' });\n }\n if (error.code === 'SPAWN_FAILED') {\n if (executable !== undefined) {\n try { resolveCommandExecutable(executable); }\n catch { return new EngineError({ kind: 'missing-cli', message: 'Devin executable is not runnable' }); }\n }\n return new EngineError({ kind: 'unknown', message: 'Devin command could not start' });\n }\n return error;\n}\n\nfunction readExport(path: string): DevinConversation | undefined {\n let text: string;\n try {\n text = readFileSync(path, 'utf8');\n } catch {\n return undefined;\n }\n try {\n return readDevinExport(JSON.parse(text));\n } catch {\n return undefined;\n }\n}\n\nexport class DevinCliEngine implements Engine {\n readonly name = ADAPTER;\n private executable: string | undefined;\n private version: Promise<string> | undefined;\n constructor(private readonly opts: DevinCliEngineOptions = {}) {}\n\n private commandExecutable(expected?: EngineSelectionRecord): string {\n const configured = this.opts.cliBinary ?? 'devin';\n if (configured.length === 0 || (!isAbsolute(configured) && basename(configured) !== configured)) {\n throw new EngineError({ kind: 'invalid-config', message: 'Devin command must be absolute or a bare name' });\n }\n if (expected && (expected.executable === null\n || (isAbsolute(configured) && configured !== expected.executable)\n || (this.executable !== undefined && this.executable !== expected.executable))) {\n throw new EngineError({ kind: 'invalid-config', message: 'Devin executable selection changed' });\n }\n try {\n this.executable ??= resolveCommandExecutable(expected?.executable ?? configured);\n return resolveCommandExecutable(this.executable);\n } catch (error) { throw devinCommandError(error, this.executable); }\n }\n\n private async observeVersion(req: AgentRequest, executable: string, signal: AbortSignal): Promise<string> {\n try {\n const result = await runOwnedCommand({\n executable, args: ['--version'], stdin: '',\n cwd: req.cwd ?? process.cwd(), env: attemptEnvironment(req) ?? {},\n ...ownedCommandIdentity({ adapter: ADAPTER, runId: req.attempt?.runId,\n leafId: req.attempt?.leafId, attemptId: req.attempt?.attemptId }),\n ...DEFAULT_OWNED_COMMAND_LIMITS,\n timeoutMs: Math.min(req.timeoutMs ?? 5_000, 5_000),\n teardownGraceMs: Math.min(req.timeoutGraceMs ?? 1_000, 1_000),\n maxOutputBytes: Math.min(req.maxOutputBytes ?? 4_096, 4_096),\n maxMemoryBytes: req.maxMemoryBytes ?? DEFAULT_OWNED_COMMAND_LIMITS.maxMemoryBytes,\n }, signal);\n if (result.aborted || signal.aborted) {\n throw new EngineError({ kind: 'aborted', message: 'Devin version observation aborted' });\n }\n if (result.timedOut) {\n throw new EngineError({ kind: 'timeout', message: 'Devin version observation timed out' });\n }\n if (result.exitCode !== 0) {\n throw new EngineError({ kind: 'unknown', message: 'Devin version command failed' });\n }\n const matched = /^devin (\\d+\\.\\d+\\.\\d+) \\([0-9a-f]+\\)$/.exec(new TextDecoder().decode(result.stdout).trim());\n if (!matched) {\n throw new EngineError({ kind: 'invalid-config', message: 'Devin version output is not recognized' });\n }\n return matched[1]!;\n } catch (error) {\n const mapped = devinCommandError(error, executable);\n if (mapped instanceof EngineError) throw mapped;\n throw new EngineError({ kind: 'unknown', message: 'Devin version observation failed' });\n }\n }\n\n async admit(\n request: Omit<AgentRequest, 'prompt'>,\n signal: AbortSignal,\n expectedSelection?: EngineSelectionRecord,\n ): Promise<EngineSelectionRecord> {\n if (signal.aborted) throw new EngineError({ kind: 'aborted', message: 'Devin admission aborted' });\n const req: AgentRequest = { ...request, prompt: '' };\n assertDevinConfiguration(req, this.opts);\n let expected: EngineSelectionRecord | undefined;\n let proposed: EngineSelectionRecord;\n try {\n expected = expectedSelection === undefined ? undefined : engineSelection(expectedSelection);\n proposed = requestedSelection(req, this.opts);\n } catch {\n throw new EngineError({ kind: 'invalid-config', message: 'invalid Devin selection' });\n }\n const executable = this.commandExecutable(expected);\n let observation = this.version;\n if (observation === undefined) {\n observation = this.observeVersion(req, executable, signal);\n this.version = observation;\n }\n let adapterVersion: string;\n try { adapterVersion = await observation; }\n catch (error) {\n if (this.version === observation) this.version = undefined;\n throw error;\n }\n if (signal.aborted) throw new EngineError({ kind: 'aborted', message: 'Devin admission aborted' });\n const selected = engineSelection({ ...proposed, executable, adapterVersion });\n if (expected && !isDeepStrictEqual(selected, expected)) {\n throw new EngineError({ kind: 'invalid-config', message: 'Devin selection changed' });\n }\n return selected;\n }\n\n async run(\n req: AgentRequest,\n onEvent: EngineEventSink,\n signal: AbortSignal,\n ): Promise<AgentResult> {\n if (signal.aborted) throw new EngineError({ kind: 'aborted', message: 'devin run aborted' });\n const { prompt: _prompt, ...admissionRequest } = req;\n const requested = await this.admit(admissionRequest, signal);\n const executable = requested.executable!;\n const dir = mkdtempSync(join(tmpdir(), 'obversa-devin-'));\n const promptFile = join(dir, 'prompt.md');\n const exportFile = join(dir, 'conversation.json');\n const env = attemptEnvironment(req);\n try {\n // Devin has no system prompt flag, so system text leads the prompt.\n writeFileSync(\n promptFile,\n req.system ? `${req.system}\\n\\n---\\n\\n${req.prompt}` : req.prompt,\n { encoding: 'utf8', mode: 0o600 },\n );\n const sub = await runOwnedCommand({\n executable,\n args: buildDevinArgs(req, this.opts, { promptFile, exportFile }),\n cwd: req.cwd ?? process.cwd(),\n env: env ?? {},\n stdin: '',\n ...ownedCommandIdentity({ adapter: ADAPTER, runId: req.attempt?.runId,\n leafId: req.attempt?.leafId, attemptId: req.attempt?.attemptId }),\n ...DEFAULT_OWNED_COMMAND_LIMITS,\n timeoutMs: req.timeoutMs ?? DEFAULT_OWNED_COMMAND_LIMITS.timeoutMs,\n teardownGraceMs: req.timeoutGraceMs ?? DEFAULT_OWNED_COMMAND_LIMITS.teardownGraceMs,\n maxOutputBytes: req.maxOutputBytes ?? DEFAULT_OWNED_COMMAND_LIMITS.maxOutputBytes,\n maxMemoryBytes: req.maxMemoryBytes ?? DEFAULT_OWNED_COMMAND_LIMITS.maxMemoryBytes,\n }, signal).catch((error: unknown) => { throw devinCommandError(error, executable); });\n\n const conversation = readExport(exportFile);\n const answered = conversation?.answered === true;\n const aborted = sub.aborted || signal.aborted;\n if (aborted && !answered) throw new EngineError({ kind: 'aborted', message: 'devin run aborted' });\n const diagnostic = scrubCapture(\n [new TextDecoder().decode(sub.stderr), new TextDecoder().decode(sub.stdout)]\n .filter((text) => text.length > 0).join('\\n'),\n env,\n DIAGNOSTIC_MAX,\n ).trim();\n const failed = aborted || sub.timedOut || sub.exitCode !== 0;\n if (failed && !answered) {\n throw new EngineError({\n kind: sub.timedOut ? 'timeout' : classifyEngineFailure(new Error(diagnostic)),\n message: `devin exited ${sub.exitCode ?? '?'}${diagnostic ? `: ${diagnostic}` : ''}`,\n });\n }\n if (conversation === undefined) {\n throw new EngineError({\n kind: 'unknown',\n message: `devin wrote no readable conversation export${diagnostic ? `: ${diagnostic}` : ''}`,\n });\n }\n\n let effective = requested;\n if (conversation.model !== undefined) {\n try {\n effective = engineSelection({\n ...requested,\n model: conversation.model,\n modelFamily: modelIdentity(conversation.model).modelFamily,\n });\n } catch {\n // A model name Devin reports but no family can be read from keeps the requested record.\n }\n }\n const parts: AgentResultPart[] = conversation.messages.map((text, index) => ({\n kind: 'assistant',\n text,\n final: answered && index === conversation.messages.length - 1,\n }));\n for (const text of conversation.messages) onEvent({ type: 'text', delta: text });\n for (const event of conversation.toolEvents) onEvent(event);\n if (!answered) {\n // A tool the permission mode does not approve is refused, and Devin\n // can then end with no answer and exit 0.\n throw new EngineIncompleteResultError(\n `devin ended without a final answer under permission mode ${permissionMode(req)}${\n diagnostic ? `: ${diagnostic}` : ''\n }`,\n { parts, usage: conversation.usage, requested, effective },\n );\n }\n onEvent({ type: 'usage', usage: conversation.usage, model: effective.model ?? 'devin' });\n return validateAgentResult({\n parts,\n usage: conversation.usage,\n requested,\n effective,\n ...(failed\n ? {\n transportFailure: {\n kind: aborted ? 'aborted' as const : sub.timedOut ? 'timeout' as const : 'unknown' as const,\n message: `devin completed but exited ${sub.exitCode ?? '?'} during teardown${\n diagnostic ? `: ${diagnostic}` : ''\n }`,\n exitCode: sub.exitCode ?? null,\n },\n }\n : {}),\n });\n } finally {\n rmSync(dir, { recursive: true, force: true });\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/atif.ts","../src/devin-cli.ts"],"names":["value"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Read the conversation file `devin --export` writes. Devin 3000.11 writes it\n * in the ATIF v1 shape: ordered steps from the system, the user and the agent,\n * with each agent step carrying its text, its tool calls, the results of those\n * calls and the model that produced it.\n */\nimport type { EngineStreamEvent, UsageReceipt } from '@obversa/api';\n\nexport interface DevinConversation {\n /** Every non-empty agent message, in order. */\n readonly messages: readonly string[];\n /** True when the conversation ends on an agent message with no tool calls. */\n readonly answered: boolean;\n /** The model named on the last agent step, when Devin names one. */\n readonly model: string | undefined;\n readonly toolEvents: readonly Extract<EngineStreamEvent, { type: 'tool' }>[];\n readonly usage: UsageReceipt;\n}\n\nfunction record(value: unknown, what: string): Record<string, unknown> {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(`Devin export ${what} is not an object`);\n }\n return value as Record<string, unknown>;\n}\n\nfunction messageText(value: unknown): string {\n if (typeof value === 'string') return value;\n if (!Array.isArray(value)) return '';\n return value\n .map((part) => (part !== null && typeof part === 'object'\n && (part as Record<string, unknown>).type === 'text'\n && typeof (part as Record<string, unknown>).text === 'string'\n ? (part as Record<string, string>).text\n : ''))\n .join('');\n}\n\nfunction tokenCount(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;\n}\n\nfunction usage(value: unknown): UsageReceipt {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n return { kind: 'unknown' };\n }\n const totals = value as Record<string, unknown>;\n const input = totals.total_prompt_tokens;\n const output = totals.total_completion_tokens;\n const cached = totals.total_cached_tokens;\n if (!tokenCount(input) || !tokenCount(output)\n || (cached != null && (!tokenCount(cached) || cached > input))) {\n return { kind: 'unknown' };\n }\n return {\n kind: 'reported',\n inputTokens: input,\n outputTokens: output,\n ...(cached == null ? {} : { cacheReadInputTokens: cached }),\n };\n}\n\nexport function readDevinExport(value: unknown): DevinConversation {\n const root = record(value, 'root');\n if (typeof root.schema_version !== 'string' || !root.schema_version.startsWith('ATIF-v1.')) {\n throw new Error('Devin export is not in the ATIF v1 shape');\n }\n if (!Array.isArray(root.steps)) throw new Error('Devin export has no steps');\n\n const messages: string[] = [];\n const toolEvents: Extract<EngineStreamEvent, { type: 'tool' }>[] = [];\n let answered = false;\n let model: string | undefined;\n for (const value of root.steps) {\n const step = record(value, 'step');\n if (step.source !== 'agent') {\n answered = false;\n continue;\n }\n if (typeof step.model_name === 'string' && step.model_name.length > 0) {\n model = step.model_name;\n }\n const calls = new Map<string, string>();\n if (Array.isArray(step.tool_calls)) {\n for (const value of step.tool_calls) {\n const call = record(value, 'tool call');\n if (typeof call.tool_call_id !== 'string' || typeof call.function_name !== 'string') {\n throw new Error('Devin export has a tool call without an id or a name');\n }\n calls.set(call.tool_call_id, call.function_name);\n toolEvents.push({ type: 'tool', name: call.function_name, phase: 'use' });\n }\n }\n const results = step.observation === undefined || step.observation === null\n ? []\n : record(step.observation, 'observation').results;\n if (Array.isArray(results)) {\n for (const value of results) {\n const id = record(value, 'tool result').source_call_id;\n const name = typeof id === 'string' ? calls.get(id) : undefined;\n if (name !== undefined) toolEvents.push({ type: 'tool', name, phase: 'result' });\n }\n }\n const text = messageText(step.message);\n if (text.length > 0) messages.push(text);\n answered = text.length > 0 && calls.size === 0;\n }\n return { messages, answered, model, toolEvents, usage: usage(root.final_metrics) };\n}\n","/**\n * Engine plugin: the `devin` CLI as a non-interactive subprocess. One fresh\n * `devin -p` process runs each attempt, with the person's own environment,\n * Devin login and Devin settings. The plugin adds only what the step needs:\n * Devin's permission mode for the workspace mode, the model when one is named,\n * and a conversation export it reads the answer from.\n */\nimport { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, isAbsolute, join } from 'node:path';\nimport { isDeepStrictEqual } from 'node:util';\nimport {\n EngineError,\n EngineIncompleteResultError,\n assertReadAccess,\n classifyEngineFailure,\n engineSelection,\n modelIdentity,\n validateAgentResult,\n type AgentRequest,\n type AgentResult,\n type AgentResultPart,\n type Engine,\n type EngineEventSink,\n type EngineSelectionRecord,\n} from '@obversa/api';\nimport {\n attemptEnvironment,\n scrubCapture,\n DEFAULT_OWNED_COMMAND_LIMITS,\n OwnedCommandError,\n ownedCommandIdentity,\n resolveCommandExecutable,\n runOwnedCommand,\n} from '@obversa/core/command';\nimport { readDevinExport, type DevinConversation } from './atif.js';\n\nconst ADAPTER = 'devin-cli';\nconst PROVIDER = 'cognition';\n/** The model a seat records when it leaves the choice of model to Devin. */\nconst DEFAULT_MODEL = 'default';\nconst DIAGNOSTIC_MAX = 700;\n/** Whether a run leaves out the person's own setup when `clean` is not set. */\nconst CLEAN_BY_DEFAULT = true;\n/** The settings a clean-mode run reads in place of the person's Devin config file. */\nconst CLEAN_CONFIG = '{}\\n';\n\nexport interface DevinCliEngineOptions {\n /** Model for requests that name none. Without a model, Devin runs its own default model, or the one your Devin settings choose with `clean: false`. */\n readonly defaultModel?: string;\n /** Absolute path or bare command name; `devin` by default. */\n readonly cliBinary?: string;\n /**\n * Run with an empty Devin config file in place of the person's own\n * `~/.config/devin/config.json`. Their own MCP servers and skills still\n * load, because Devin has no switch to leave them out. The repository's\n * instruction files still apply, and the run keeps the person's login.\n * On by default; `false` runs on the person's own setup.\n */\n readonly clean?: boolean;\n}\n\nexport interface DevinSeat {\n readonly engine: DevinCliEngine;\n readonly identity: {\n readonly adapter: 'devin-cli';\n readonly provider: 'cognition';\n readonly modelFamily: string;\n readonly model: string;\n readonly tools: readonly string[];\n };\n}\n\nexport interface DevinSeatOptions {\n readonly clean?: boolean;\n}\n\n/**\n * Create the Devin seat used by declarative team workflows. Without a model,\n * Devin runs its own default model, or the one your Devin settings choose with\n * `clean: false`, and the seat records the model as `default`.\n */\nexport function devin(model?: string, options: DevinSeatOptions = {}): DevinSeat {\n if (model !== undefined && !model.trim()) throw new TypeError('devin model must not be empty');\n return {\n engine: new DevinCliEngine({\n ...(model === undefined ? {} : { defaultModel: model }),\n ...(options.clean === undefined ? {} : { clean: options.clean }),\n }),\n identity: {\n adapter: ADAPTER,\n provider: PROVIDER,\n modelFamily: modelIdentity(model ?? DEFAULT_MODEL).modelFamily,\n model: model ?? DEFAULT_MODEL,\n tools: ['read', 'edit', 'exec'],\n },\n };\n}\n\nfunction modelFor(req: AgentRequest, opts: DevinCliEngineOptions): string | undefined {\n const model = req.model ?? opts.defaultModel;\n return model === undefined || model === DEFAULT_MODEL ? undefined : model;\n}\n\n/** Devin's permission mode for a workspace mode: read-only tools, or those plus workspace edits. */\nfunction permissionMode(req: AgentRequest): 'auto' | 'accept-edits' {\n return req.workspaceMode === 'write' ? 'accept-edits' : 'auto';\n}\n\n/**\n * Build the `devin` argv for one attempt. Exported so the flag wiring is\n * testable without spawning a process.\n */\nexport function buildDevinArgs(\n req: AgentRequest,\n opts: DevinCliEngineOptions,\n files: { readonly promptFile: string; readonly exportFile: string; readonly configFile?: string },\n): string[] {\n const clean = opts.clean ?? CLEAN_BY_DEFAULT;\n try {\n assertReadAccess(req);\n if (clean && files.configFile === undefined) {\n throw new TypeError('devin clean mode requires an empty config file');\n }\n if (req.tools?.length === 0) {\n throw new TypeError('devin cannot turn its tools off; choose an engine that supports tools: []');\n }\n if (req.workspaceMode === 'none') {\n throw new TypeError('devin has no mode without workspace access; choose read or write');\n }\n } catch (cause) {\n throw new EngineError({\n kind: 'invalid-config',\n message: cause instanceof Error ? cause.message : 'invalid Devin workspace configuration',\n cause,\n });\n }\n const model = modelFor(req, opts);\n return [\n '-p',\n '--prompt-file', files.promptFile,\n '--export', files.exportFile,\n '--permission-mode', permissionMode(req),\n // Print mode cannot show Devin's folder trust prompt; without this flag\n // every folder the person has not opened in Devin before refuses to run.\n '--respect-workspace-trust', 'false',\n ...(clean ? ['--config', files.configFile!] : []),\n ...(model === undefined ? [] : ['--model', model]),\n ];\n}\n\nfunction requestedSelection(req: AgentRequest, opts: DevinCliEngineOptions): EngineSelectionRecord {\n const model = modelFor(req, opts);\n return engineSelection({\n adapter: ADAPTER,\n provider: PROVIDER,\n modelFamily: model === undefined ? null : modelIdentity(model).modelFamily,\n model: model ?? null,\n capabilities: req.tools ?? [],\n });\n}\n\nfunction assertDevinConfiguration(req: AgentRequest, opts: DevinCliEngineOptions): void {\n buildDevinArgs(req, opts, { promptFile: 'prompt', exportFile: 'export', configFile: 'config' });\n try {\n const env = attemptEnvironment(req) ?? {};\n const limits = {\n timeoutMs: req.timeoutMs ?? DEFAULT_OWNED_COMMAND_LIMITS.timeoutMs,\n teardownGraceMs: req.timeoutGraceMs ?? DEFAULT_OWNED_COMMAND_LIMITS.teardownGraceMs,\n maxOutputBytes: req.maxOutputBytes ?? DEFAULT_OWNED_COMMAND_LIMITS.maxOutputBytes,\n maxMemoryBytes: req.maxMemoryBytes ?? DEFAULT_OWNED_COMMAND_LIMITS.maxMemoryBytes,\n };\n if (!isAbsolute(req.cwd ?? process.cwd())\n || Object.values(env).some((value) => typeof value !== 'string')\n || !Number.isSafeInteger(limits.timeoutMs) || limits.timeoutMs < 1\n || !Number.isSafeInteger(limits.teardownGraceMs) || limits.teardownGraceMs < 0\n || limits.timeoutMs + limits.teardownGraceMs > 2_147_483_647\n || !Number.isSafeInteger(limits.maxOutputBytes) || limits.maxOutputBytes < 0\n || !Number.isSafeInteger(limits.maxMemoryBytes) || limits.maxMemoryBytes < 1) {\n throw new Error('invalid Devin command request');\n }\n ownedCommandIdentity({ adapter: ADAPTER, runId: req.attempt?.runId,\n leafId: req.attempt?.leafId, attemptId: req.attempt?.attemptId });\n } catch {\n throw new EngineError({ kind: 'invalid-config', message: 'invalid Devin command configuration' });\n }\n}\n\nfunction devinCommandError(error: unknown, executable?: string): unknown {\n if (!(error instanceof OwnedCommandError)) return error;\n if (error.code === 'INVALID_EXECUTABLE') {\n return new EngineError({ kind: 'missing-cli', message: 'Devin executable is not runnable' });\n }\n if (error.code === 'INVALID_COMMAND') {\n return new EngineError({ kind: 'invalid-config', message: 'invalid Devin command request' });\n }\n if (error.code === 'SPAWN_FAILED') {\n if (executable !== undefined) {\n try { resolveCommandExecutable(executable); }\n catch { return new EngineError({ kind: 'missing-cli', message: 'Devin executable is not runnable' }); }\n }\n return new EngineError({ kind: 'unknown', message: 'Devin command could not start' });\n }\n return error;\n}\n\nfunction readExport(path: string): DevinConversation | undefined {\n let text: string;\n try {\n text = readFileSync(path, 'utf8');\n } catch {\n return undefined;\n }\n try {\n return readDevinExport(JSON.parse(text));\n } catch {\n return undefined;\n }\n}\n\nexport class DevinCliEngine implements Engine {\n readonly name = ADAPTER;\n private executable: string | undefined;\n private version: Promise<string> | undefined;\n constructor(private readonly opts: DevinCliEngineOptions = {}) {}\n\n private commandExecutable(expected?: EngineSelectionRecord): string {\n const configured = this.opts.cliBinary ?? 'devin';\n if (configured.length === 0 || (!isAbsolute(configured) && basename(configured) !== configured)) {\n throw new EngineError({ kind: 'invalid-config', message: 'Devin command must be absolute or a bare name' });\n }\n if (expected && (expected.executable === null\n || (isAbsolute(configured) && configured !== expected.executable)\n || (this.executable !== undefined && this.executable !== expected.executable))) {\n throw new EngineError({ kind: 'invalid-config', message: 'Devin executable selection changed' });\n }\n try {\n this.executable ??= resolveCommandExecutable(expected?.executable ?? configured);\n return resolveCommandExecutable(this.executable);\n } catch (error) { throw devinCommandError(error, this.executable); }\n }\n\n private async observeVersion(req: AgentRequest, executable: string, signal: AbortSignal): Promise<string> {\n try {\n const result = await runOwnedCommand({\n executable, args: ['--version'], stdin: '',\n cwd: req.cwd ?? process.cwd(), env: attemptEnvironment(req) ?? {},\n ...ownedCommandIdentity({ adapter: ADAPTER, runId: req.attempt?.runId,\n leafId: req.attempt?.leafId, attemptId: req.attempt?.attemptId }),\n ...DEFAULT_OWNED_COMMAND_LIMITS,\n timeoutMs: Math.min(req.timeoutMs ?? 5_000, 5_000),\n teardownGraceMs: Math.min(req.timeoutGraceMs ?? 1_000, 1_000),\n maxOutputBytes: Math.min(req.maxOutputBytes ?? 4_096, 4_096),\n maxMemoryBytes: req.maxMemoryBytes ?? DEFAULT_OWNED_COMMAND_LIMITS.maxMemoryBytes,\n }, signal);\n if (result.aborted || signal.aborted) {\n throw new EngineError({ kind: 'aborted', message: 'Devin version observation aborted' });\n }\n if (result.timedOut) {\n throw new EngineError({ kind: 'timeout', message: 'Devin version observation timed out' });\n }\n if (result.exitCode !== 0) {\n throw new EngineError({ kind: 'unknown', message: 'Devin version command failed' });\n }\n const matched = /^devin (\\d+\\.\\d+\\.\\d+) \\([0-9a-f]+\\)$/.exec(new TextDecoder().decode(result.stdout).trim());\n if (!matched) {\n throw new EngineError({ kind: 'invalid-config', message: 'Devin version output is not recognized' });\n }\n return matched[1]!;\n } catch (error) {\n const mapped = devinCommandError(error, executable);\n if (mapped instanceof EngineError) throw mapped;\n throw new EngineError({ kind: 'unknown', message: 'Devin version observation failed' });\n }\n }\n\n async admit(\n request: Omit<AgentRequest, 'prompt'>,\n signal: AbortSignal,\n expectedSelection?: EngineSelectionRecord,\n ): Promise<EngineSelectionRecord> {\n if (signal.aborted) throw new EngineError({ kind: 'aborted', message: 'Devin admission aborted' });\n const req: AgentRequest = { ...request, prompt: '' };\n assertDevinConfiguration(req, this.opts);\n let expected: EngineSelectionRecord | undefined;\n let proposed: EngineSelectionRecord;\n try {\n expected = expectedSelection === undefined ? undefined : engineSelection(expectedSelection);\n proposed = requestedSelection(req, this.opts);\n } catch {\n throw new EngineError({ kind: 'invalid-config', message: 'invalid Devin selection' });\n }\n const executable = this.commandExecutable(expected);\n let observation = this.version;\n if (observation === undefined) {\n observation = this.observeVersion(req, executable, signal);\n this.version = observation;\n }\n let adapterVersion: string;\n try { adapterVersion = await observation; }\n catch (error) {\n if (this.version === observation) this.version = undefined;\n throw error;\n }\n if (signal.aborted) throw new EngineError({ kind: 'aborted', message: 'Devin admission aborted' });\n const selected = engineSelection({ ...proposed, executable, adapterVersion });\n if (expected && !isDeepStrictEqual(selected, expected)) {\n throw new EngineError({ kind: 'invalid-config', message: 'Devin selection changed' });\n }\n return selected;\n }\n\n async run(\n req: AgentRequest,\n onEvent: EngineEventSink,\n signal: AbortSignal,\n ): Promise<AgentResult> {\n if (signal.aborted) throw new EngineError({ kind: 'aborted', message: 'devin run aborted' });\n const { prompt: _prompt, ...admissionRequest } = req;\n const requested = await this.admit(admissionRequest, signal);\n const executable = requested.executable!;\n const dir = mkdtempSync(join(tmpdir(), 'obversa-devin-'));\n const promptFile = join(dir, 'prompt.md');\n const exportFile = join(dir, 'conversation.json');\n const configFile = join(dir, 'config.json');\n const env = attemptEnvironment(req);\n try {\n // Devin has no system prompt flag, so system text leads the prompt.\n writeFileSync(\n promptFile,\n req.system ? `${req.system}\\n\\n---\\n\\n${req.prompt}` : req.prompt,\n { encoding: 'utf8', mode: 0o600 },\n );\n if (this.opts.clean ?? CLEAN_BY_DEFAULT) {\n writeFileSync(configFile, CLEAN_CONFIG, { encoding: 'utf8', mode: 0o600 });\n }\n const sub = await runOwnedCommand({\n executable,\n args: buildDevinArgs(req, this.opts, { promptFile, exportFile, configFile }),\n cwd: req.cwd ?? process.cwd(),\n env: env ?? {},\n stdin: '',\n ...ownedCommandIdentity({ adapter: ADAPTER, runId: req.attempt?.runId,\n leafId: req.attempt?.leafId, attemptId: req.attempt?.attemptId }),\n ...DEFAULT_OWNED_COMMAND_LIMITS,\n timeoutMs: req.timeoutMs ?? DEFAULT_OWNED_COMMAND_LIMITS.timeoutMs,\n teardownGraceMs: req.timeoutGraceMs ?? DEFAULT_OWNED_COMMAND_LIMITS.teardownGraceMs,\n maxOutputBytes: req.maxOutputBytes ?? DEFAULT_OWNED_COMMAND_LIMITS.maxOutputBytes,\n maxMemoryBytes: req.maxMemoryBytes ?? DEFAULT_OWNED_COMMAND_LIMITS.maxMemoryBytes,\n }, signal).catch((error: unknown) => { throw devinCommandError(error, executable); });\n\n const conversation = readExport(exportFile);\n const answered = conversation?.answered === true;\n const aborted = sub.aborted || signal.aborted;\n if (aborted && !answered) throw new EngineError({ kind: 'aborted', message: 'devin run aborted' });\n const diagnostic = scrubCapture(\n [new TextDecoder().decode(sub.stderr), new TextDecoder().decode(sub.stdout)]\n .filter((text) => text.length > 0).join('\\n'),\n env,\n DIAGNOSTIC_MAX,\n ).trim();\n const failed = aborted || sub.timedOut || sub.exitCode !== 0;\n if (failed && !answered) {\n throw new EngineError({\n kind: sub.timedOut ? 'timeout' : classifyEngineFailure(new Error(diagnostic)),\n message: `devin exited ${sub.exitCode ?? '?'}${diagnostic ? `: ${diagnostic}` : ''}`,\n });\n }\n if (conversation === undefined) {\n throw new EngineError({\n kind: 'unknown',\n message: `devin wrote no readable conversation export${diagnostic ? `: ${diagnostic}` : ''}`,\n });\n }\n\n let effective = requested;\n if (conversation.model !== undefined) {\n try {\n effective = engineSelection({\n ...requested,\n model: conversation.model,\n modelFamily: modelIdentity(conversation.model).modelFamily,\n });\n } catch {\n // A model name Devin reports but no family can be read from keeps the requested record.\n }\n }\n const parts: AgentResultPart[] = conversation.messages.map((text, index) => ({\n kind: 'assistant',\n text,\n final: answered && index === conversation.messages.length - 1,\n }));\n for (const text of conversation.messages) onEvent({ type: 'text', delta: text });\n for (const event of conversation.toolEvents) onEvent(event);\n if (!answered) {\n // A tool the permission mode does not approve is refused, and Devin\n // can then end with no answer and exit 0.\n throw new EngineIncompleteResultError(\n `devin ended without a final answer under permission mode ${permissionMode(req)}${\n diagnostic ? `: ${diagnostic}` : ''\n }`,\n { parts, usage: conversation.usage, requested, effective },\n );\n }\n onEvent({ type: 'usage', usage: conversation.usage, model: effective.model ?? 'devin' });\n return validateAgentResult({\n parts,\n usage: conversation.usage,\n requested,\n effective,\n ...(failed\n ? {\n transportFailure: {\n kind: aborted ? 'aborted' as const : sub.timedOut ? 'timeout' as const : 'unknown' as const,\n message: `devin completed but exited ${sub.exitCode ?? '?'} during teardown${\n diagnostic ? `: ${diagnostic}` : ''\n }`,\n exitCode: sub.exitCode ?? null,\n },\n }\n : {}),\n });\n } finally {\n rmSync(dir, { recursive: true, force: true });\n }\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@obversa/engine-devin-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Run engine requests through a fresh Devin CLI process.",
|
|
5
5
|
"author": "Jonny Neill <jonnyneill@hotmail.com>",
|
|
6
6
|
"type": "module",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"LICENSE"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@obversa/api": "^0.2.
|
|
30
|
-
"@obversa/core": "^0.2.
|
|
29
|
+
"@obversa/api": "^0.2.4",
|
|
30
|
+
"@obversa/core": "^0.2.4"
|
|
31
31
|
},
|
|
32
32
|
"keywords": [
|
|
33
33
|
"agent",
|