@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 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, `devin()` runs the default model from your Devin settings.
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, Devin login and Devin settings. A
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
@@ -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 one, Devin uses the person's default. */
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 the default model from the person's own Devin settings and the
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
- function devin(model) {
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(model === void 0 ? {} : { defaultModel: model }),
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.0",
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.3",
30
- "@obversa/core": "^0.2.3"
29
+ "@obversa/api": "^0.2.4",
30
+ "@obversa/core": "^0.2.4"
31
31
  },
32
32
  "keywords": [
33
33
  "agent",