@code-yeongyu/senpi-ai 2026.9.11 → 2026.9.12-3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/README.md +39 -4
  2. package/dist/api/anthropic-messages.d.ts.map +1 -1
  3. package/dist/api/anthropic-messages.js +8 -1
  4. package/dist/api/anthropic-messages.js.map +1 -1
  5. package/dist/api/cloudflare-ai-binding.d.ts +77 -0
  6. package/dist/api/cloudflare-ai-binding.d.ts.map +1 -0
  7. package/dist/api/cloudflare-ai-binding.js +72 -0
  8. package/dist/api/cloudflare-ai-binding.js.map +1 -0
  9. package/dist/api/cursor-agent/measure.d.ts +11 -0
  10. package/dist/api/cursor-agent/measure.d.ts.map +1 -1
  11. package/dist/api/cursor-agent/measure.js +18 -0
  12. package/dist/api/cursor-agent/measure.js.map +1 -1
  13. package/dist/api/cursor-agent.d.ts +1 -1
  14. package/dist/api/cursor-agent.d.ts.map +1 -1
  15. package/dist/api/cursor-agent.js +5 -1
  16. package/dist/api/cursor-agent.js.map +1 -1
  17. package/dist/api/devin-agent/discovery.d.ts +2 -0
  18. package/dist/api/devin-agent/discovery.d.ts.map +1 -1
  19. package/dist/api/devin-agent/discovery.js +96 -51
  20. package/dist/api/devin-agent/discovery.js.map +1 -1
  21. package/dist/api/devin-agent/gen/cascade_pb.d.ts +389 -1
  22. package/dist/api/devin-agent/gen/cascade_pb.d.ts.map +1 -1
  23. package/dist/api/devin-agent/gen/cascade_pb.js +132 -4
  24. package/dist/api/devin-agent/gen/cascade_pb.js.map +1 -1
  25. package/dist/api/devin-agent/metadata.d.ts +34 -4
  26. package/dist/api/devin-agent/metadata.d.ts.map +1 -1
  27. package/dist/api/devin-agent/metadata.js +41 -8
  28. package/dist/api/devin-agent/metadata.js.map +1 -1
  29. package/dist/api/devin-agent/paths.d.ts +20 -0
  30. package/dist/api/devin-agent/paths.d.ts.map +1 -1
  31. package/dist/api/devin-agent/paths.js +20 -0
  32. package/dist/api/devin-agent/paths.js.map +1 -1
  33. package/dist/api/devin-agent/request.d.ts +18 -6
  34. package/dist/api/devin-agent/request.d.ts.map +1 -1
  35. package/dist/api/devin-agent/request.js +77 -35
  36. package/dist/api/devin-agent/request.js.map +1 -1
  37. package/dist/api/devin-agent/stream-state.d.ts +9 -3
  38. package/dist/api/devin-agent/stream-state.d.ts.map +1 -1
  39. package/dist/api/devin-agent/stream-state.js +30 -38
  40. package/dist/api/devin-agent/stream-state.js.map +1 -1
  41. package/dist/api/devin-agent/trailer.d.ts +16 -0
  42. package/dist/api/devin-agent/trailer.d.ts.map +1 -0
  43. package/dist/api/devin-agent/trailer.js +69 -0
  44. package/dist/api/devin-agent/trailer.js.map +1 -0
  45. package/dist/api/devin-agent/unary.d.ts +26 -0
  46. package/dist/api/devin-agent/unary.d.ts.map +1 -0
  47. package/dist/api/devin-agent/unary.js +61 -0
  48. package/dist/api/devin-agent/unary.js.map +1 -0
  49. package/dist/api/devin-agent/wire.d.ts +6 -4
  50. package/dist/api/devin-agent/wire.d.ts.map +1 -1
  51. package/dist/api/devin-agent/wire.js +6 -4
  52. package/dist/api/devin-agent/wire.js.map +1 -1
  53. package/dist/api/devin-agent.d.ts +13 -5
  54. package/dist/api/devin-agent.d.ts.map +1 -1
  55. package/dist/api/devin-agent.js +76 -21
  56. package/dist/api/devin-agent.js.map +1 -1
  57. package/dist/api/mistral-conversations.js +4 -1
  58. package/dist/api/mistral-conversations.js.map +1 -1
  59. package/dist/api/openai-codex-responses.d.ts.map +1 -1
  60. package/dist/api/openai-codex-responses.js +6 -3
  61. package/dist/api/openai-codex-responses.js.map +1 -1
  62. package/dist/api/openai-responses-shared.d.ts.map +1 -1
  63. package/dist/api/openai-responses-shared.js +4 -1
  64. package/dist/api/openai-responses-shared.js.map +1 -1
  65. package/dist/api/openai-responses.d.ts.map +1 -1
  66. package/dist/api/openai-responses.js +13 -3
  67. package/dist/api/openai-responses.js.map +1 -1
  68. package/dist/auth/oauth/devin.d.ts +5 -0
  69. package/dist/auth/oauth/devin.d.ts.map +1 -1
  70. package/dist/auth/oauth/devin.js +7 -2
  71. package/dist/auth/oauth/devin.js.map +1 -1
  72. package/dist/cursor/context-limit-store.d.ts +32 -0
  73. package/dist/cursor/context-limit-store.d.ts.map +1 -0
  74. package/dist/cursor/context-limit-store.js +62 -0
  75. package/dist/cursor/context-limit-store.js.map +1 -0
  76. package/dist/cursor/store-migration.d.ts.map +1 -1
  77. package/dist/cursor/store-migration.js +2 -1
  78. package/dist/cursor/store-migration.js.map +1 -1
  79. package/dist/index.d.ts +2 -1
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +2 -1
  82. package/dist/index.js.map +1 -1
  83. package/dist/model.d.ts +11 -1
  84. package/dist/model.d.ts.map +1 -1
  85. package/dist/model.js.map +1 -1
  86. package/dist/models.d.ts +1 -0
  87. package/dist/models.d.ts.map +1 -1
  88. package/dist/models.js +5 -2
  89. package/dist/models.js.map +1 -1
  90. package/dist/openai-responses-compat.d.ts +1 -1
  91. package/dist/openai-responses-compat.d.ts.map +1 -1
  92. package/dist/openai-responses-compat.js.map +1 -1
  93. package/dist/providers/cloudflare-ai-gateway.d.ts.map +1 -1
  94. package/dist/providers/cloudflare-ai-gateway.js +4 -0
  95. package/dist/providers/cloudflare-ai-gateway.js.map +1 -1
  96. package/dist/providers/cursor.d.ts.map +1 -1
  97. package/dist/providers/cursor.js +2 -1
  98. package/dist/providers/cursor.js.map +1 -1
  99. package/dist/providers/data/.manifest.json +1 -1
  100. package/dist/providers/data/amazon-bedrock.json +1 -1
  101. package/dist/providers/data/azure-openai-responses.json +1 -1
  102. package/dist/providers/data/baseten.json +1 -1
  103. package/dist/providers/data/deepseek.json +1 -1
  104. package/dist/providers/data/fireworks.json +1 -1
  105. package/dist/providers/data/github-copilot.json +1 -1
  106. package/dist/providers/data/openai-codex.json +1 -1
  107. package/dist/providers/data/openrouter.json +1 -1
  108. package/dist/providers/data/qwen-token-plan-cn.json +1 -1
  109. package/dist/providers/data/qwen-token-plan-individual.json +1 -1
  110. package/dist/providers/data/qwen-token-plan.json +1 -1
  111. package/dist/providers/data/venice.json +1 -1
  112. package/dist/providers/data/vercel-ai-gateway.json +1 -1
  113. package/dist/providers/data/xai.json +1 -1
  114. package/dist/providers/devin.d.ts.map +1 -1
  115. package/dist/providers/devin.js +3 -3
  116. package/dist/providers/devin.js.map +1 -1
  117. package/dist/providers/devin.models.d.ts +4 -2
  118. package/dist/providers/devin.models.d.ts.map +1 -1
  119. package/dist/providers/devin.models.js +18 -9
  120. package/dist/providers/devin.models.js.map +1 -1
  121. package/dist/providers/faux.js +5 -5
  122. package/dist/providers/faux.js.map +1 -1
  123. package/dist/providers/opencode-go.d.ts.map +1 -1
  124. package/dist/providers/opencode-go.js +4 -3
  125. package/dist/providers/opencode-go.js.map +1 -1
  126. package/dist/providers/opencode-headers.d.ts +4 -0
  127. package/dist/providers/opencode-headers.d.ts.map +1 -0
  128. package/dist/providers/opencode-headers.js +22 -0
  129. package/dist/providers/opencode-headers.js.map +1 -0
  130. package/dist/providers/opencode.d.ts.map +1 -1
  131. package/dist/providers/opencode.js +5 -4
  132. package/dist/providers/opencode.js.map +1 -1
  133. package/dist/types.d.ts +16 -6
  134. package/dist/types.d.ts.map +1 -1
  135. package/dist/types.js.map +1 -1
  136. package/dist/utils/assistant-message-frame.d.ts +77 -0
  137. package/dist/utils/assistant-message-frame.d.ts.map +1 -0
  138. package/dist/utils/assistant-message-frame.js +427 -0
  139. package/dist/utils/assistant-message-frame.js.map +1 -0
  140. package/dist/utils/cursor-context-limit.d.ts +12 -0
  141. package/dist/utils/cursor-context-limit.d.ts.map +1 -0
  142. package/dist/utils/cursor-context-limit.js +93 -0
  143. package/dist/utils/cursor-context-limit.js.map +1 -0
  144. package/dist/utils/event-stream.d.ts.map +1 -1
  145. package/dist/utils/event-stream.js +25 -5
  146. package/dist/utils/event-stream.js.map +1 -1
  147. package/dist/utils/prompt-cache-ttl.d.ts +1 -1
  148. package/dist/utils/prompt-cache-ttl.d.ts.map +1 -1
  149. package/dist/utils/prompt-cache-ttl.js +5 -1
  150. package/dist/utils/prompt-cache-ttl.js.map +1 -1
  151. package/dist/utils/retry-profile/types.d.ts +10 -1
  152. package/dist/utils/retry-profile/types.d.ts.map +1 -1
  153. package/dist/utils/retry-profile/types.js.map +1 -1
  154. package/dist/utils/retry.d.ts +13 -2
  155. package/dist/utils/retry.d.ts.map +1 -1
  156. package/dist/utils/retry.js +18 -7
  157. package/dist/utils/retry.js.map +1 -1
  158. package/dist/utils/uuid.d.ts +2 -2
  159. package/dist/utils/uuid.d.ts.map +1 -1
  160. package/dist/utils/uuid.js +36 -31
  161. package/dist/utils/uuid.js.map +1 -1
  162. package/package.json +6 -6
  163. package/dist/api/cloudflare-gateway-binding.d.ts +0 -69
  164. package/dist/api/cloudflare-gateway-binding.d.ts.map +0 -1
  165. package/dist/api/cloudflare-gateway-binding.js +0 -159
  166. package/dist/api/cloudflare-gateway-binding.js.map +0 -1
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Unary Cascade RPCs (`GetUserJwt`, `AssignModel`, `GetCliModelConfigs`).
3
+ *
4
+ * Unlike the streaming chat call these carry a bare protobuf body both ways.
5
+ * Edges variously answer with plain or gzipped protobuf, so decoding tries the
6
+ * bytes as-is before falling back to gunzip. Discovery reaches this module from
7
+ * the provider factory, which is root-reachable, so the gunzip path uses the
8
+ * web `DecompressionStream` rather than `node:zlib`.
9
+ */
10
+ import { type DescMessage, type MessageInitShape, type MessageShape } from "@bufbuild/protobuf";
11
+ export declare class DevinUnaryError extends Error {
12
+ readonly rpc: string;
13
+ readonly status: number;
14
+ constructor(rpc: string, status: number, detail: string);
15
+ }
16
+ export interface DevinUnaryInput<TRequest extends DescMessage, TResponse extends DescMessage> {
17
+ baseUrl: string;
18
+ path: string;
19
+ requestSchema: TRequest;
20
+ request: MessageInitShape<TRequest>;
21
+ responseSchema: TResponse;
22
+ signal?: AbortSignal;
23
+ }
24
+ export declare function postDevinUnary<TRequest extends DescMessage, TResponse extends DescMessage>(input: DevinUnaryInput<TRequest, TResponse>): Promise<MessageShape<TResponse>>;
25
+ export declare function decodeDevinUnary<TSchema extends DescMessage>(schema: TSchema, payload: Uint8Array): Promise<MessageShape<TSchema> | undefined>;
26
+ //# sourceMappingURL=unary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unary.d.ts","sourceRoot":"","sources":["../../../src/api/devin-agent/unary.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAEN,KAAK,WAAW,EAEhB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EAEjB,MAAM,oBAAoB,CAAC;AAG5B,qBAAa,eAAgB,SAAQ,KAAK;IACzC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,YAAY,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAKtD;CACD;AAED,MAAM,WAAW,eAAe,CAAC,QAAQ,SAAS,WAAW,EAAE,SAAS,SAAS,WAAW;IAC3F,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,QAAQ,CAAC;IACxB,OAAO,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACpC,cAAc,EAAE,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,wBAAsB,cAAc,CAAC,QAAQ,SAAS,WAAW,EAAE,SAAS,SAAS,WAAW,EAC/F,KAAK,EAAE,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC,GACzC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAclC;AAED,wBAAsB,gBAAgB,CAAC,OAAO,SAAS,WAAW,EACjE,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,UAAU,GACjB,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,CAU5C"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Unary Cascade RPCs (`GetUserJwt`, `AssignModel`, `GetCliModelConfigs`).
3
+ *
4
+ * Unlike the streaming chat call these carry a bare protobuf body both ways.
5
+ * Edges variously answer with plain or gzipped protobuf, so decoding tries the
6
+ * bytes as-is before falling back to gunzip. Discovery reaches this module from
7
+ * the provider factory, which is root-reachable, so the gunzip path uses the
8
+ * web `DecompressionStream` rather than `node:zlib`.
9
+ */
10
+ import { create, fromBinary, toBinary, } from "@bufbuild/protobuf";
11
+ import { DEVIN_UNARY_HEADERS } from "./paths.js";
12
+ export class DevinUnaryError extends Error {
13
+ constructor(rpc, status, detail) {
14
+ super(`Devin ${rpc} failed (HTTP ${status})${detail ? `: ${detail}` : ""}`);
15
+ this.name = "DevinUnaryError";
16
+ this.rpc = rpc;
17
+ this.status = status;
18
+ }
19
+ }
20
+ export async function postDevinUnary(input) {
21
+ const response = await fetch(input.baseUrl + input.path, {
22
+ method: "POST",
23
+ headers: DEVIN_UNARY_HEADERS,
24
+ body: copyOf(toBinary(input.requestSchema, create(input.requestSchema, input.request))),
25
+ signal: input.signal,
26
+ });
27
+ const payload = new Uint8Array(await response.arrayBuffer());
28
+ if (!response.ok) {
29
+ throw new DevinUnaryError(rpcName(input.path), response.status, new TextDecoder().decode(payload).slice(0, 500));
30
+ }
31
+ const decoded = await decodeDevinUnary(input.responseSchema, payload);
32
+ if (!decoded)
33
+ throw new DevinUnaryError(rpcName(input.path), response.status, "response is not a protobuf message");
34
+ return decoded;
35
+ }
36
+ export async function decodeDevinUnary(schema, payload) {
37
+ try {
38
+ return fromBinary(schema, payload);
39
+ }
40
+ catch {
41
+ try {
42
+ return fromBinary(schema, await gunzip(payload));
43
+ }
44
+ catch {
45
+ return undefined;
46
+ }
47
+ }
48
+ }
49
+ async function gunzip(payload) {
50
+ const inflated = new Blob([copyOf(payload)]).stream().pipeThrough(new DecompressionStream("gzip"));
51
+ return new Uint8Array(await new Response(inflated).arrayBuffer());
52
+ }
53
+ function rpcName(path) {
54
+ return path.slice(path.lastIndexOf("/") + 1);
55
+ }
56
+ function copyOf(source) {
57
+ const out = new Uint8Array(source.byteLength);
58
+ out.set(source);
59
+ return out;
60
+ }
61
+ //# sourceMappingURL=unary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unary.js","sourceRoot":"","sources":["../../../src/api/devin-agent/unary.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Unary Cascade RPCs (`GetUserJwt`, `AssignModel`, `GetCliModelConfigs`).\n *\n * Unlike the streaming chat call these carry a bare protobuf body both ways.\n * Edges variously answer with plain or gzipped protobuf, so decoding tries the\n * bytes as-is before falling back to gunzip. Discovery reaches this module from\n * the provider factory, which is root-reachable, so the gunzip path uses the\n * web `DecompressionStream` rather than `node:zlib`.\n */\n\nimport {\n\tcreate,\n\ttype DescMessage,\n\tfromBinary,\n\ttype MessageInitShape,\n\ttype MessageShape,\n\ttoBinary,\n} from \"@bufbuild/protobuf\";\nimport { DEVIN_UNARY_HEADERS } from \"./paths.ts\";\n\nexport class DevinUnaryError extends Error {\n\treadonly rpc: string;\n\treadonly status: number;\n\n\tconstructor(rpc: string, status: number, detail: string) {\n\t\tsuper(`Devin ${rpc} failed (HTTP ${status})${detail ? `: ${detail}` : \"\"}`);\n\t\tthis.name = \"DevinUnaryError\";\n\t\tthis.rpc = rpc;\n\t\tthis.status = status;\n\t}\n}\n\nexport interface DevinUnaryInput<TRequest extends DescMessage, TResponse extends DescMessage> {\n\tbaseUrl: string;\n\tpath: string;\n\trequestSchema: TRequest;\n\trequest: MessageInitShape<TRequest>;\n\tresponseSchema: TResponse;\n\tsignal?: AbortSignal;\n}\n\nexport async function postDevinUnary<TRequest extends DescMessage, TResponse extends DescMessage>(\n\tinput: DevinUnaryInput<TRequest, TResponse>,\n): Promise<MessageShape<TResponse>> {\n\tconst response = await fetch(input.baseUrl + input.path, {\n\t\tmethod: \"POST\",\n\t\theaders: DEVIN_UNARY_HEADERS,\n\t\tbody: copyOf(toBinary(input.requestSchema, create(input.requestSchema, input.request))),\n\t\tsignal: input.signal,\n\t});\n\tconst payload = new Uint8Array(await response.arrayBuffer());\n\tif (!response.ok) {\n\t\tthrow new DevinUnaryError(rpcName(input.path), response.status, new TextDecoder().decode(payload).slice(0, 500));\n\t}\n\tconst decoded = await decodeDevinUnary(input.responseSchema, payload);\n\tif (!decoded) throw new DevinUnaryError(rpcName(input.path), response.status, \"response is not a protobuf message\");\n\treturn decoded;\n}\n\nexport async function decodeDevinUnary<TSchema extends DescMessage>(\n\tschema: TSchema,\n\tpayload: Uint8Array,\n): Promise<MessageShape<TSchema> | undefined> {\n\ttry {\n\t\treturn fromBinary(schema, payload);\n\t} catch {\n\t\ttry {\n\t\t\treturn fromBinary(schema, await gunzip(payload));\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n}\n\nasync function gunzip(payload: Uint8Array): Promise<Uint8Array<ArrayBuffer>> {\n\tconst inflated = new Blob([copyOf(payload)]).stream().pipeThrough(new DecompressionStream(\"gzip\"));\n\treturn new Uint8Array(await new Response(inflated).arrayBuffer());\n}\n\nfunction rpcName(path: string): string {\n\treturn path.slice(path.lastIndexOf(\"/\") + 1);\n}\n\nfunction copyOf(source: Uint8Array<ArrayBufferLike>): Uint8Array<ArrayBuffer> {\n\tconst out = new Uint8Array(source.byteLength);\n\tout.set(source);\n\treturn out;\n}\n"]}
@@ -1,6 +1,8 @@
1
- /** Cascade wire surface: paths, identity metadata, frame codec and request building. */
1
+ /** Cascade wire surface: paths, identity metadata, frame codec, unary RPCs and request building. */
2
2
  export { type DevinFrame, decodeDevinFrames, encodeDevinFrame as encodeDevinRequestFrame } from "./frames.ts";
3
- export { devinCliMetadata, normalizeDevinSessionToken } from "./metadata.ts";
4
- export { DEVIN_CHAT_MESSAGE_PATH, DEVIN_CLI_MODEL_CONFIGS_PATH, DEVIN_DEFAULT_BASE_URL, DEVIN_MAX_FRAME_PAYLOAD, } from "./paths.ts";
5
- export { buildDevinChatRequest, DEVIN_DEFAULT_STOP_PATTERNS, type DevinChatRequestInput } from "./request.ts";
3
+ export { DEVIN_CLI_IDENTITY, DEVIN_DISCOVERY_IDENTITY, DEVIN_SUPPORTED_MODEL_DISPLAYS, devinCliMetadata, devinDiscoveryMetadata, normalizeDevinSessionToken, } from "./metadata.ts";
4
+ export { DEVIN_ASSIGN_MODEL_PATH, DEVIN_CHAT_HEADERS, DEVIN_CHAT_MESSAGE_PATH, DEVIN_CLI_MODEL_CONFIGS_PATH, DEVIN_DEFAULT_BASE_URL, DEVIN_MAX_FRAME_PAYLOAD, DEVIN_UNARY_HEADERS, DEVIN_USER_JWT_PATH, } from "./paths.ts";
5
+ export { buildDevinChatRequest, buildDevinRouterPrompt, DEVIN_DEFAULT_STOP_PATTERNS, type DevinChatRequestInput, type DevinModelAssignment, } from "./request.ts";
6
+ export { type DevinTrailerError, readDevinTrailerError } from "./trailer.ts";
7
+ export { DevinUnaryError, type DevinUnaryInput, decodeDevinUnary, postDevinUnary } from "./unary.ts";
6
8
  //# sourceMappingURL=wire.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wire.d.ts","sourceRoot":"","sources":["../../../src/api/devin-agent/wire.ts"],"names":[],"mappings":"AAAA,wFAAwF;AAExF,OAAO,EAAE,KAAK,UAAU,EAAE,iBAAiB,EAAE,gBAAgB,IAAI,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC9G,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EACN,uBAAuB,EACvB,4BAA4B,EAC5B,sBAAsB,EACtB,uBAAuB,GACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,KAAK,qBAAqB,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"wire.d.ts","sourceRoot":"","sources":["../../../src/api/devin-agent/wire.ts"],"names":[],"mappings":"AAAA,oGAAoG;AAEpG,OAAO,EAAE,KAAK,UAAU,EAAE,iBAAiB,EAAE,gBAAgB,IAAI,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC9G,OAAO,EACN,kBAAkB,EAClB,wBAAwB,EACxB,8BAA8B,EAC9B,gBAAgB,EAChB,sBAAsB,EACtB,0BAA0B,GAC1B,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,uBAAuB,EACvB,kBAAkB,EAClB,uBAAuB,EACvB,4BAA4B,EAC5B,sBAAsB,EACtB,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,qBAAqB,EACrB,sBAAsB,EACtB,2BAA2B,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GACzB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
@@ -1,6 +1,8 @@
1
- /** Cascade wire surface: paths, identity metadata, frame codec and request building. */
1
+ /** Cascade wire surface: paths, identity metadata, frame codec, unary RPCs and request building. */
2
2
  export { decodeDevinFrames, encodeDevinFrame as encodeDevinRequestFrame } from "./frames.js";
3
- export { devinCliMetadata, normalizeDevinSessionToken } from "./metadata.js";
4
- export { DEVIN_CHAT_MESSAGE_PATH, DEVIN_CLI_MODEL_CONFIGS_PATH, DEVIN_DEFAULT_BASE_URL, DEVIN_MAX_FRAME_PAYLOAD, } from "./paths.js";
5
- export { buildDevinChatRequest, DEVIN_DEFAULT_STOP_PATTERNS } from "./request.js";
3
+ export { DEVIN_CLI_IDENTITY, DEVIN_DISCOVERY_IDENTITY, DEVIN_SUPPORTED_MODEL_DISPLAYS, devinCliMetadata, devinDiscoveryMetadata, normalizeDevinSessionToken, } from "./metadata.js";
4
+ export { DEVIN_ASSIGN_MODEL_PATH, DEVIN_CHAT_HEADERS, DEVIN_CHAT_MESSAGE_PATH, DEVIN_CLI_MODEL_CONFIGS_PATH, DEVIN_DEFAULT_BASE_URL, DEVIN_MAX_FRAME_PAYLOAD, DEVIN_UNARY_HEADERS, DEVIN_USER_JWT_PATH, } from "./paths.js";
5
+ export { buildDevinChatRequest, buildDevinRouterPrompt, DEVIN_DEFAULT_STOP_PATTERNS, } from "./request.js";
6
+ export { readDevinTrailerError } from "./trailer.js";
7
+ export { DevinUnaryError, decodeDevinUnary, postDevinUnary } from "./unary.js";
6
8
  //# sourceMappingURL=wire.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"wire.js","sourceRoot":"","sources":["../../../src/api/devin-agent/wire.ts"],"names":[],"mappings":"AAAA,wFAAwF;AAExF,OAAO,EAAmB,iBAAiB,EAAE,gBAAgB,IAAI,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC9G,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EACN,uBAAuB,EACvB,4BAA4B,EAC5B,sBAAsB,EACtB,uBAAuB,GACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,2BAA2B,EAA8B,MAAM,cAAc,CAAC","sourcesContent":["/** Cascade wire surface: paths, identity metadata, frame codec and request building. */\n\nexport { type DevinFrame, decodeDevinFrames, encodeDevinFrame as encodeDevinRequestFrame } from \"./frames.ts\";\nexport { devinCliMetadata, normalizeDevinSessionToken } from \"./metadata.ts\";\nexport {\n\tDEVIN_CHAT_MESSAGE_PATH,\n\tDEVIN_CLI_MODEL_CONFIGS_PATH,\n\tDEVIN_DEFAULT_BASE_URL,\n\tDEVIN_MAX_FRAME_PAYLOAD,\n} from \"./paths.ts\";\nexport { buildDevinChatRequest, DEVIN_DEFAULT_STOP_PATTERNS, type DevinChatRequestInput } from \"./request.ts\";\n"]}
1
+ {"version":3,"file":"wire.js","sourceRoot":"","sources":["../../../src/api/devin-agent/wire.ts"],"names":[],"mappings":"AAAA,oGAAoG;AAEpG,OAAO,EAAmB,iBAAiB,EAAE,gBAAgB,IAAI,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC9G,OAAO,EACN,kBAAkB,EAClB,wBAAwB,EACxB,8BAA8B,EAC9B,gBAAgB,EAChB,sBAAsB,EACtB,0BAA0B,GAC1B,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,uBAAuB,EACvB,kBAAkB,EAClB,uBAAuB,EACvB,4BAA4B,EAC5B,sBAAsB,EACtB,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,qBAAqB,EACrB,sBAAsB,EACtB,2BAA2B,GAG3B,MAAM,cAAc,CAAC;AACtB,OAAO,EAA0B,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAwB,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC","sourcesContent":["/** Cascade wire surface: paths, identity metadata, frame codec, unary RPCs and request building. */\n\nexport { type DevinFrame, decodeDevinFrames, encodeDevinFrame as encodeDevinRequestFrame } from \"./frames.ts\";\nexport {\n\tDEVIN_CLI_IDENTITY,\n\tDEVIN_DISCOVERY_IDENTITY,\n\tDEVIN_SUPPORTED_MODEL_DISPLAYS,\n\tdevinCliMetadata,\n\tdevinDiscoveryMetadata,\n\tnormalizeDevinSessionToken,\n} from \"./metadata.ts\";\nexport {\n\tDEVIN_ASSIGN_MODEL_PATH,\n\tDEVIN_CHAT_HEADERS,\n\tDEVIN_CHAT_MESSAGE_PATH,\n\tDEVIN_CLI_MODEL_CONFIGS_PATH,\n\tDEVIN_DEFAULT_BASE_URL,\n\tDEVIN_MAX_FRAME_PAYLOAD,\n\tDEVIN_UNARY_HEADERS,\n\tDEVIN_USER_JWT_PATH,\n} from \"./paths.ts\";\nexport {\n\tbuildDevinChatRequest,\n\tbuildDevinRouterPrompt,\n\tDEVIN_DEFAULT_STOP_PATTERNS,\n\ttype DevinChatRequestInput,\n\ttype DevinModelAssignment,\n} from \"./request.ts\";\nexport { type DevinTrailerError, readDevinTrailerError } from \"./trailer.ts\";\nexport { DevinUnaryError, type DevinUnaryInput, decodeDevinUnary, postDevinUnary } from \"./unary.ts\";\n"]}
@@ -1,11 +1,19 @@
1
1
  /**
2
2
  * Devin (Cognition/Codeium Cascade) agent API.
3
3
  *
4
- * One `GetChatMessage` server-streaming Connect call per assistant turn. The
5
- * request is a single gzipped frame; the response is a frame sequence of
6
- * deltas, closed by a JSON trailer frame. Cascade reports text, thinking and
7
- * tool calls as separate delta fields on the same message, so this adapter owns
8
- * the block bookkeeping senpi's event protocol expects.
4
+ * One assistant turn is up to three RPCs, exactly as the released Devin CLI
5
+ * performs them:
6
+ * 1. `GetUserJwt` mints the short-lived user JWT the chat call must carry and
7
+ * names the account's API host, which can differ from the seeded one;
8
+ * 2. `AssignModel` resolves a server-side router into a concrete model uid plus
9
+ * the JWT that authorizes it (router models only);
10
+ * 3. `GetChatMessage` streams the turn: a single gzipped Connect frame out, a
11
+ * frame sequence of deltas back, closed by a JSON trailer that either
12
+ * carries the rejection or is empty.
13
+ *
14
+ * Cascade reports text, thinking and tool calls as separate delta fields on the
15
+ * same message, so this adapter owns the block bookkeeping senpi's event
16
+ * protocol expects.
9
17
  */
10
18
  import type { StreamFunction } from "../types.ts";
11
19
  import type { DevinAgentOptions } from "./devin-agent/types.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"devin-agent.d.ts","sourceRoot":"","sources":["../../src/api/devin-agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAoC,cAAc,EAAY,MAAM,aAAa,CAAC;AAI9F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAUhE,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,aAAa,EAAE,iBAAiB,CAQnE,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,aAAa,EAAE,iBAAiB,CAAU,CAAC"}
1
+ {"version":3,"file":"devin-agent.d.ts","sourceRoot":"","sources":["../../src/api/devin-agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAoC,cAAc,EAAY,MAAM,aAAa,CAAC;AAW9F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAiBhE,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,aAAa,EAAE,iBAAiB,CAQnE,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,aAAa,EAAE,iBAAiB,CAAU,CAAC"}
@@ -1,16 +1,24 @@
1
1
  /**
2
2
  * Devin (Cognition/Codeium Cascade) agent API.
3
3
  *
4
- * One `GetChatMessage` server-streaming Connect call per assistant turn. The
5
- * request is a single gzipped frame; the response is a frame sequence of
6
- * deltas, closed by a JSON trailer frame. Cascade reports text, thinking and
7
- * tool calls as separate delta fields on the same message, so this adapter owns
8
- * the block bookkeeping senpi's event protocol expects.
4
+ * One assistant turn is up to three RPCs, exactly as the released Devin CLI
5
+ * performs them:
6
+ * 1. `GetUserJwt` mints the short-lived user JWT the chat call must carry and
7
+ * names the account's API host, which can differ from the seeded one;
8
+ * 2. `AssignModel` resolves a server-side router into a concrete model uid plus
9
+ * the JWT that authorizes it (router models only);
10
+ * 3. `GetChatMessage` streams the turn: a single gzipped Connect frame out, a
11
+ * frame sequence of deltas back, closed by a JSON trailer that either
12
+ * carries the rejection or is empty.
13
+ *
14
+ * Cascade reports text, thinking and tool calls as separate delta fields on the
15
+ * same message, so this adapter owns the block bookkeeping senpi's event
16
+ * protocol expects.
9
17
  */
10
18
  import { AssistantMessageEventStream } from "../utils/event-stream.js";
11
- import { GetChatMessageRequestSchema, GetChatMessageResponseSchema } from "./devin-agent/gen/cascade_pb.js";
12
- import { applyDevinResponse } from "./devin-agent/stream-state.js";
13
- import { buildDevinChatRequest, DEVIN_CHAT_MESSAGE_PATH, DEVIN_DEFAULT_BASE_URL, decodeDevinFrames, encodeDevinRequestFrame, normalizeDevinSessionToken, } from "./devin-agent/wire.js";
19
+ import { AssignModelRequestSchema, AssignModelResponseSchema, GetChatMessageRequestSchema, GetChatMessageResponseSchema, GetUserJwtRequestSchema, GetUserJwtResponseSchema, } from "./devin-agent/gen/cascade_pb.js";
20
+ import { applyDevinResponse, createDevinStreamState } from "./devin-agent/stream-state.js";
21
+ import { buildDevinChatRequest, buildDevinRouterPrompt, DEVIN_ASSIGN_MODEL_PATH, DEVIN_CHAT_HEADERS, DEVIN_CHAT_MESSAGE_PATH, DEVIN_DEFAULT_BASE_URL, DEVIN_USER_JWT_PATH, decodeDevinFrames, devinCliMetadata, encodeDevinRequestFrame, postDevinUnary, readDevinTrailerError, } from "./devin-agent/wire.js";
14
22
  export const stream = (model, context, options) => {
15
23
  const events = new AssistantMessageEventStream();
16
24
  void run(model, context, events, options);
@@ -35,28 +43,31 @@ async function run(model, context, events, options) {
35
43
  stopReason: "stop",
36
44
  timestamp: Date.now(),
37
45
  };
38
- const state = { textIndex: undefined, thinkingIndex: undefined, toolCalls: new Map() };
46
+ const state = createDevinStreamState();
39
47
  const signal = options?.signal;
40
48
  try {
41
49
  events.push({ type: "start", partial: output });
50
+ const baseUrl = (model.baseUrl || DEVIN_DEFAULT_BASE_URL).replace(/\/+$/, "");
51
+ const cascadeId = options?.cascadeId ?? crypto.randomUUID();
52
+ const session = await mintUserJwt(baseUrl, options?.apiKey, signal);
53
+ const assignment = model.compat?.modelRouter === true
54
+ ? await assignModel(model, context, session.chatBaseUrl, cascadeId, options?.apiKey, signal)
55
+ : undefined;
56
+ if (assignment)
57
+ output.responseModel = assignment.modelUid;
42
58
  const request = buildDevinChatRequest({
43
59
  model,
44
60
  context,
45
61
  apiKey: options?.apiKey,
46
- cascadeId: options?.cascadeId,
47
- maxTokens: options?.maxTokens,
48
- temperature: options?.temperature,
62
+ userJwt: session.userJwt,
63
+ cascadeId,
64
+ ...(assignment ? { assignment } : {}),
65
+ ...(options?.maxTokens !== undefined ? { maxTokens: options.maxTokens } : {}),
66
+ ...(options?.temperature !== undefined ? { temperature: options.temperature } : {}),
49
67
  });
50
- const baseUrl = model.baseUrl || DEVIN_DEFAULT_BASE_URL;
51
- const response = await fetch(baseUrl + DEVIN_CHAT_MESSAGE_PATH, {
68
+ const response = await fetch(session.chatBaseUrl + DEVIN_CHAT_MESSAGE_PATH, {
52
69
  method: "POST",
53
- headers: {
54
- "content-type": "application/connect+proto",
55
- "connect-protocol-version": "1",
56
- "connect-content-encoding": "gzip",
57
- "connect-accept-encoding": "gzip",
58
- authorization: `Bearer ${normalizeDevinSessionToken(options?.apiKey)}`,
59
- },
70
+ headers: DEVIN_CHAT_HEADERS,
60
71
  body: encodeDevinRequestFrame(GetChatMessageRequestSchema, request),
61
72
  signal,
62
73
  });
@@ -67,6 +78,11 @@ async function run(model, context, events, options) {
67
78
  for await (const frame of decodeDevinFrames(response.body, GetChatMessageResponseSchema)) {
68
79
  if (frame.message)
69
80
  applyDevinResponse(frame.message, output, events, state);
81
+ if (frame.trailer !== undefined) {
82
+ const rejection = readDevinTrailerError(frame.trailer);
83
+ if (rejection)
84
+ throw new Error(rejection.formatted);
85
+ }
70
86
  }
71
87
  finalizeBlocks(output, events, state);
72
88
  // Cascade can close a turn that carries a tool call without ever sending an
@@ -96,6 +112,45 @@ async function run(model, context, events, options) {
96
112
  events.end();
97
113
  }
98
114
  }
115
+ async function mintUserJwt(baseUrl, apiKey, signal) {
116
+ const response = await postDevinUnary({
117
+ baseUrl,
118
+ path: DEVIN_USER_JWT_PATH,
119
+ requestSchema: GetUserJwtRequestSchema,
120
+ request: { metadata: devinCliMetadata(apiKey) },
121
+ responseSchema: GetUserJwtResponseSchema,
122
+ ...(signal ? { signal } : {}),
123
+ });
124
+ if (!response.userJwt)
125
+ throw new Error("Devin GetUserJwt returned an empty user JWT");
126
+ const customHost = response.customApiServerUrl.trim().replace(/\/+$/, "");
127
+ return { userJwt: response.userJwt, chatBaseUrl: customHost || baseUrl };
128
+ }
129
+ /**
130
+ * A router uid is never a legal chat model uid, so a failed assignment fails the
131
+ * turn instead of falling back to sending the router id to GetChatMessage.
132
+ */
133
+ async function assignModel(model, context, baseUrl, cascadeId, apiKey, signal) {
134
+ const routerPrompt = buildDevinRouterPrompt(context.messages);
135
+ const response = await postDevinUnary({
136
+ baseUrl,
137
+ path: DEVIN_ASSIGN_MODEL_PATH,
138
+ requestSchema: AssignModelRequestSchema,
139
+ request: {
140
+ metadata: devinCliMetadata(apiKey),
141
+ modelRouterUid: model.upstreamModelId ?? model.id,
142
+ cascadeId,
143
+ ...(routerPrompt ? { chatMessagePrompt: routerPrompt } : {}),
144
+ },
145
+ responseSchema: AssignModelResponseSchema,
146
+ ...(signal ? { signal } : {}),
147
+ });
148
+ const assignment = response.assignment;
149
+ if (!assignment?.modelUid || !assignment.assignmentJwt) {
150
+ throw new Error("Devin AssignModel returned no model uid and assignment JWT");
151
+ }
152
+ return { modelUid: assignment.modelUid, assignmentJwt: assignment.assignmentJwt };
153
+ }
99
154
  /** Narrows a settled stop reason to the three senpi accepts on a done event. */
100
155
  function doneReasonOf(stopReason) {
101
156
  switch (stopReason) {
@@ -1 +1 @@
1
- {"version":3,"file":"devin-agent.js","sourceRoot":"","sources":["../../src/api/devin-agent.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Devin (Cognition/Codeium Cascade) agent API.\n *\n * One `GetChatMessage` server-streaming Connect call per assistant turn. The\n * request is a single gzipped frame; the response is a frame sequence of\n * deltas, closed by a JSON trailer frame. Cascade reports text, thinking and\n * tool calls as separate delta fields on the same message, so this adapter owns\n * the block bookkeeping senpi's event protocol expects.\n */\n\nimport type { AssistantMessage, Context, Model, StreamFunction, ToolCall } from \"../types.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { GetChatMessageRequestSchema, GetChatMessageResponseSchema } from \"./devin-agent/gen/cascade_pb.ts\";\nimport { applyDevinResponse, type DevinStreamState } from \"./devin-agent/stream-state.ts\";\nimport type { DevinAgentOptions } from \"./devin-agent/types.ts\";\nimport {\n\tbuildDevinChatRequest,\n\tDEVIN_CHAT_MESSAGE_PATH,\n\tDEVIN_DEFAULT_BASE_URL,\n\tdecodeDevinFrames,\n\tencodeDevinRequestFrame,\n\tnormalizeDevinSessionToken,\n} from \"./devin-agent/wire.ts\";\n\nexport const stream: StreamFunction<\"devin-agent\", DevinAgentOptions> = (\n\tmodel: Model<\"devin-agent\">,\n\tcontext: Context,\n\toptions?: DevinAgentOptions,\n) => {\n\tconst events = new AssistantMessageEventStream();\n\tvoid run(model, context, events, options);\n\treturn events;\n};\n\nexport const streamSimple: StreamFunction<\"devin-agent\", DevinAgentOptions> = stream;\n\nasync function run(\n\tmodel: Model<\"devin-agent\">,\n\tcontext: Context,\n\tevents: AssistantMessageEventStream,\n\toptions: DevinAgentOptions | undefined,\n): Promise<void> {\n\tconst output: AssistantMessage = {\n\t\trole: \"assistant\",\n\t\tcontent: [],\n\t\tapi: \"devin-agent\",\n\t\tprovider: model.provider,\n\t\tmodel: model.id,\n\t\tusage: {\n\t\t\tinput: 0,\n\t\t\toutput: 0,\n\t\t\tcacheRead: 0,\n\t\t\tcacheWrite: 0,\n\t\t\ttotalTokens: 0,\n\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t},\n\t\tstopReason: \"stop\",\n\t\ttimestamp: Date.now(),\n\t};\n\tconst state: DevinStreamState = { textIndex: undefined, thinkingIndex: undefined, toolCalls: new Map() };\n\tconst signal = options?.signal;\n\n\ttry {\n\t\tevents.push({ type: \"start\", partial: output });\n\t\tconst request = buildDevinChatRequest({\n\t\t\tmodel,\n\t\t\tcontext,\n\t\t\tapiKey: options?.apiKey,\n\t\t\tcascadeId: options?.cascadeId,\n\t\t\tmaxTokens: options?.maxTokens,\n\t\t\ttemperature: options?.temperature,\n\t\t});\n\t\tconst baseUrl = model.baseUrl || DEVIN_DEFAULT_BASE_URL;\n\t\tconst response = await fetch(baseUrl + DEVIN_CHAT_MESSAGE_PATH, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"content-type\": \"application/connect+proto\",\n\t\t\t\t\"connect-protocol-version\": \"1\",\n\t\t\t\t\"connect-content-encoding\": \"gzip\",\n\t\t\t\t\"connect-accept-encoding\": \"gzip\",\n\t\t\t\tauthorization: `Bearer ${normalizeDevinSessionToken(options?.apiKey)}`,\n\t\t\t},\n\t\t\tbody: encodeDevinRequestFrame(GetChatMessageRequestSchema, request),\n\t\t\tsignal,\n\t\t});\n\t\tawait options?.onResponse?.({ status: response.status, headers: headersOf(response) }, model);\n\n\t\tif (!response.ok || !response.body) {\n\t\t\tthrow new Error(`Devin request failed (HTTP ${response.status})${await detail(response)}`);\n\t\t}\n\n\t\tfor await (const frame of decodeDevinFrames(response.body, GetChatMessageResponseSchema)) {\n\t\t\tif (frame.message) applyDevinResponse(frame.message, output, events, state);\n\t\t}\n\n\t\tfinalizeBlocks(output, events, state);\n\t\t// Cascade can close a turn that carries a tool call without ever sending an\n\t\t// explicit stop reason. Only the default \"stop\" is upgraded: a server-reported\n\t\t// \"length\" means the turn was truncated, and a truncated tool call must not be\n\t\t// advertised as a complete one.\n\t\tif (output.stopReason === \"stop\" && output.content.some(isToolCall)) output.stopReason = \"toolUse\";\n\t\t// Cascade reports a server error or a content filter as a stop reason on an\n\t\t// otherwise well-formed stream. senpi's protocol has no \"done because it\n\t\t// failed\", so that turn terminates as an error event, not a done event.\n\t\tif (output.stopReason === \"error\") {\n\t\t\toutput.errorMessage ??= \"Devin ended the turn with a server error or a content filter\";\n\t\t\tevents.push({ type: \"error\", reason: \"error\", error: output });\n\t\t\tevents.end();\n\t\t\treturn;\n\t\t}\n\t\tevents.push({ type: \"done\", reason: doneReasonOf(output.stopReason), message: output });\n\t\tevents.end();\n\t} catch (error) {\n\t\tfinalizeBlocks(output, events, state);\n\t\tconst aborted = signal?.aborted === true || (error instanceof Error && error.name === \"AbortError\");\n\t\toutput.stopReason = aborted ? \"aborted\" : \"error\";\n\t\toutput.errorMessage = aborted ? \"Request was aborted\" : messageOf(error);\n\t\tevents.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\tevents.end();\n\t}\n}\n\n/** Narrows a settled stop reason to the three senpi accepts on a done event. */\nfunction doneReasonOf(stopReason: AssistantMessage[\"stopReason\"]): \"stop\" | \"length\" | \"toolUse\" {\n\tswitch (stopReason) {\n\t\tcase \"length\":\n\t\t\treturn \"length\";\n\t\tcase \"toolUse\":\n\t\t\treturn \"toolUse\";\n\t\tdefault:\n\t\t\treturn \"stop\";\n\t}\n}\n\nfunction headersOf(response: Response): Record<string, string> {\n\tconst headers: Record<string, string> = {};\n\tresponse.headers.forEach((value, key) => {\n\t\theaders[key] = value;\n\t});\n\treturn headers;\n}\n\nfunction isToolCall(content: AssistantMessage[\"content\"][number]): content is ToolCall {\n\treturn content.type === \"toolCall\";\n}\n\nfunction finalizeBlocks(output: AssistantMessage, events: AssistantMessageEventStream, state: DevinStreamState): void {\n\tif (state.thinkingIndex !== undefined) {\n\t\tconst block = output.content[state.thinkingIndex];\n\t\tif (block?.type === \"thinking\") {\n\t\t\tevents.push({\n\t\t\t\ttype: \"thinking_end\",\n\t\t\t\tcontentIndex: state.thinkingIndex,\n\t\t\t\tcontent: block.thinking,\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t}\n\t\tstate.thinkingIndex = undefined;\n\t}\n\tif (state.textIndex !== undefined) {\n\t\tconst block = output.content[state.textIndex];\n\t\tif (block?.type === \"text\") {\n\t\t\tevents.push({ type: \"text_end\", contentIndex: state.textIndex, content: block.text, partial: output });\n\t\t}\n\t\tstate.textIndex = undefined;\n\t}\n\tfor (const [, entry] of state.toolCalls) {\n\t\tconst block = output.content[entry.contentIndex];\n\t\tif (block?.type === \"toolCall\") {\n\t\t\tevents.push({ type: \"toolcall_end\", contentIndex: entry.contentIndex, toolCall: block, partial: output });\n\t\t}\n\t}\n\tstate.toolCalls.clear();\n}\n\nasync function detail(response: Response): Promise<string> {\n\ttry {\n\t\tconst body = await response.text();\n\t\treturn body ? `: ${body.slice(0, 500)}` : \"\";\n\t} catch {\n\t\treturn \"\";\n\t}\n}\n\nfunction messageOf(error: unknown): string {\n\tif (error instanceof Error) return error.message;\n\treturn String(error);\n}\n"]}
1
+ {"version":3,"file":"devin-agent.js","sourceRoot":"","sources":["../../src/api/devin-agent.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Devin (Cognition/Codeium Cascade) agent API.\n *\n * One assistant turn is up to three RPCs, exactly as the released Devin CLI\n * performs them:\n * 1. `GetUserJwt` mints the short-lived user JWT the chat call must carry and\n * names the account's API host, which can differ from the seeded one;\n * 2. `AssignModel` resolves a server-side router into a concrete model uid plus\n * the JWT that authorizes it (router models only);\n * 3. `GetChatMessage` streams the turn: a single gzipped Connect frame out, a\n * frame sequence of deltas back, closed by a JSON trailer that either\n * carries the rejection or is empty.\n *\n * Cascade reports text, thinking and tool calls as separate delta fields on the\n * same message, so this adapter owns the block bookkeeping senpi's event\n * protocol expects.\n */\n\nimport type { AssistantMessage, Context, Model, StreamFunction, ToolCall } from \"../types.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport {\n\tAssignModelRequestSchema,\n\tAssignModelResponseSchema,\n\tGetChatMessageRequestSchema,\n\tGetChatMessageResponseSchema,\n\tGetUserJwtRequestSchema,\n\tGetUserJwtResponseSchema,\n} from \"./devin-agent/gen/cascade_pb.ts\";\nimport { applyDevinResponse, createDevinStreamState, type DevinStreamState } from \"./devin-agent/stream-state.ts\";\nimport type { DevinAgentOptions } from \"./devin-agent/types.ts\";\nimport {\n\tbuildDevinChatRequest,\n\tbuildDevinRouterPrompt,\n\tDEVIN_ASSIGN_MODEL_PATH,\n\tDEVIN_CHAT_HEADERS,\n\tDEVIN_CHAT_MESSAGE_PATH,\n\tDEVIN_DEFAULT_BASE_URL,\n\tDEVIN_USER_JWT_PATH,\n\ttype DevinModelAssignment,\n\tdecodeDevinFrames,\n\tdevinCliMetadata,\n\tencodeDevinRequestFrame,\n\tpostDevinUnary,\n\treadDevinTrailerError,\n} from \"./devin-agent/wire.ts\";\n\nexport const stream: StreamFunction<\"devin-agent\", DevinAgentOptions> = (\n\tmodel: Model<\"devin-agent\">,\n\tcontext: Context,\n\toptions?: DevinAgentOptions,\n) => {\n\tconst events = new AssistantMessageEventStream();\n\tvoid run(model, context, events, options);\n\treturn events;\n};\n\nexport const streamSimple: StreamFunction<\"devin-agent\", DevinAgentOptions> = stream;\n\ninterface DevinSession {\n\tuserJwt: string;\n\t/** Host the account is provisioned on; GetUserJwt may move it off the seed. */\n\tchatBaseUrl: string;\n}\n\nasync function run(\n\tmodel: Model<\"devin-agent\">,\n\tcontext: Context,\n\tevents: AssistantMessageEventStream,\n\toptions: DevinAgentOptions | undefined,\n): Promise<void> {\n\tconst output: AssistantMessage = {\n\t\trole: \"assistant\",\n\t\tcontent: [],\n\t\tapi: \"devin-agent\",\n\t\tprovider: model.provider,\n\t\tmodel: model.id,\n\t\tusage: {\n\t\t\tinput: 0,\n\t\t\toutput: 0,\n\t\t\tcacheRead: 0,\n\t\t\tcacheWrite: 0,\n\t\t\ttotalTokens: 0,\n\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t},\n\t\tstopReason: \"stop\",\n\t\ttimestamp: Date.now(),\n\t};\n\tconst state = createDevinStreamState();\n\tconst signal = options?.signal;\n\n\ttry {\n\t\tevents.push({ type: \"start\", partial: output });\n\t\tconst baseUrl = (model.baseUrl || DEVIN_DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n\t\tconst cascadeId = options?.cascadeId ?? crypto.randomUUID();\n\t\tconst session = await mintUserJwt(baseUrl, options?.apiKey, signal);\n\t\tconst assignment =\n\t\t\tmodel.compat?.modelRouter === true\n\t\t\t\t? await assignModel(model, context, session.chatBaseUrl, cascadeId, options?.apiKey, signal)\n\t\t\t\t: undefined;\n\t\tif (assignment) output.responseModel = assignment.modelUid;\n\n\t\tconst request = buildDevinChatRequest({\n\t\t\tmodel,\n\t\t\tcontext,\n\t\t\tapiKey: options?.apiKey,\n\t\t\tuserJwt: session.userJwt,\n\t\t\tcascadeId,\n\t\t\t...(assignment ? { assignment } : {}),\n\t\t\t...(options?.maxTokens !== undefined ? { maxTokens: options.maxTokens } : {}),\n\t\t\t...(options?.temperature !== undefined ? { temperature: options.temperature } : {}),\n\t\t});\n\t\tconst response = await fetch(session.chatBaseUrl + DEVIN_CHAT_MESSAGE_PATH, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: DEVIN_CHAT_HEADERS,\n\t\t\tbody: encodeDevinRequestFrame(GetChatMessageRequestSchema, request),\n\t\t\tsignal,\n\t\t});\n\t\tawait options?.onResponse?.({ status: response.status, headers: headersOf(response) }, model);\n\n\t\tif (!response.ok || !response.body) {\n\t\t\tthrow new Error(`Devin request failed (HTTP ${response.status})${await detail(response)}`);\n\t\t}\n\n\t\tfor await (const frame of decodeDevinFrames(response.body, GetChatMessageResponseSchema)) {\n\t\t\tif (frame.message) applyDevinResponse(frame.message, output, events, state);\n\t\t\tif (frame.trailer !== undefined) {\n\t\t\t\tconst rejection = readDevinTrailerError(frame.trailer);\n\t\t\t\tif (rejection) throw new Error(rejection.formatted);\n\t\t\t}\n\t\t}\n\n\t\tfinalizeBlocks(output, events, state);\n\t\t// Cascade can close a turn that carries a tool call without ever sending an\n\t\t// explicit stop reason. Only the default \"stop\" is upgraded: a server-reported\n\t\t// \"length\" means the turn was truncated, and a truncated tool call must not be\n\t\t// advertised as a complete one.\n\t\tif (output.stopReason === \"stop\" && output.content.some(isToolCall)) output.stopReason = \"toolUse\";\n\t\t// Cascade reports a server error or a content filter as a stop reason on an\n\t\t// otherwise well-formed stream. senpi's protocol has no \"done because it\n\t\t// failed\", so that turn terminates as an error event, not a done event.\n\t\tif (output.stopReason === \"error\") {\n\t\t\toutput.errorMessage ??= \"Devin ended the turn with a server error or a content filter\";\n\t\t\tevents.push({ type: \"error\", reason: \"error\", error: output });\n\t\t\tevents.end();\n\t\t\treturn;\n\t\t}\n\t\tevents.push({ type: \"done\", reason: doneReasonOf(output.stopReason), message: output });\n\t\tevents.end();\n\t} catch (error) {\n\t\tfinalizeBlocks(output, events, state);\n\t\tconst aborted = signal?.aborted === true || (error instanceof Error && error.name === \"AbortError\");\n\t\toutput.stopReason = aborted ? \"aborted\" : \"error\";\n\t\toutput.errorMessage = aborted ? \"Request was aborted\" : messageOf(error);\n\t\tevents.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\tevents.end();\n\t}\n}\n\nasync function mintUserJwt(\n\tbaseUrl: string,\n\tapiKey: string | undefined,\n\tsignal: AbortSignal | undefined,\n): Promise<DevinSession> {\n\tconst response = await postDevinUnary({\n\t\tbaseUrl,\n\t\tpath: DEVIN_USER_JWT_PATH,\n\t\trequestSchema: GetUserJwtRequestSchema,\n\t\trequest: { metadata: devinCliMetadata(apiKey) },\n\t\tresponseSchema: GetUserJwtResponseSchema,\n\t\t...(signal ? { signal } : {}),\n\t});\n\tif (!response.userJwt) throw new Error(\"Devin GetUserJwt returned an empty user JWT\");\n\tconst customHost = response.customApiServerUrl.trim().replace(/\\/+$/, \"\");\n\treturn { userJwt: response.userJwt, chatBaseUrl: customHost || baseUrl };\n}\n\n/**\n * A router uid is never a legal chat model uid, so a failed assignment fails the\n * turn instead of falling back to sending the router id to GetChatMessage.\n */\nasync function assignModel(\n\tmodel: Model<\"devin-agent\">,\n\tcontext: Context,\n\tbaseUrl: string,\n\tcascadeId: string,\n\tapiKey: string | undefined,\n\tsignal: AbortSignal | undefined,\n): Promise<DevinModelAssignment> {\n\tconst routerPrompt = buildDevinRouterPrompt(context.messages);\n\tconst response = await postDevinUnary({\n\t\tbaseUrl,\n\t\tpath: DEVIN_ASSIGN_MODEL_PATH,\n\t\trequestSchema: AssignModelRequestSchema,\n\t\trequest: {\n\t\t\tmetadata: devinCliMetadata(apiKey),\n\t\t\tmodelRouterUid: model.upstreamModelId ?? model.id,\n\t\t\tcascadeId,\n\t\t\t...(routerPrompt ? { chatMessagePrompt: routerPrompt } : {}),\n\t\t},\n\t\tresponseSchema: AssignModelResponseSchema,\n\t\t...(signal ? { signal } : {}),\n\t});\n\tconst assignment = response.assignment;\n\tif (!assignment?.modelUid || !assignment.assignmentJwt) {\n\t\tthrow new Error(\"Devin AssignModel returned no model uid and assignment JWT\");\n\t}\n\treturn { modelUid: assignment.modelUid, assignmentJwt: assignment.assignmentJwt };\n}\n\n/** Narrows a settled stop reason to the three senpi accepts on a done event. */\nfunction doneReasonOf(stopReason: AssistantMessage[\"stopReason\"]): \"stop\" | \"length\" | \"toolUse\" {\n\tswitch (stopReason) {\n\t\tcase \"length\":\n\t\t\treturn \"length\";\n\t\tcase \"toolUse\":\n\t\t\treturn \"toolUse\";\n\t\tdefault:\n\t\t\treturn \"stop\";\n\t}\n}\n\nfunction headersOf(response: Response): Record<string, string> {\n\tconst headers: Record<string, string> = {};\n\tresponse.headers.forEach((value, key) => {\n\t\theaders[key] = value;\n\t});\n\treturn headers;\n}\n\nfunction isToolCall(content: AssistantMessage[\"content\"][number]): content is ToolCall {\n\treturn content.type === \"toolCall\";\n}\n\nfunction finalizeBlocks(output: AssistantMessage, events: AssistantMessageEventStream, state: DevinStreamState): void {\n\tif (state.thinkingIndex !== undefined) {\n\t\tconst block = output.content[state.thinkingIndex];\n\t\tif (block?.type === \"thinking\") {\n\t\t\tevents.push({\n\t\t\t\ttype: \"thinking_end\",\n\t\t\t\tcontentIndex: state.thinkingIndex,\n\t\t\t\tcontent: block.thinking,\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t}\n\t\tstate.thinkingIndex = undefined;\n\t}\n\tif (state.textIndex !== undefined) {\n\t\tconst block = output.content[state.textIndex];\n\t\tif (block?.type === \"text\") {\n\t\t\tevents.push({ type: \"text_end\", contentIndex: state.textIndex, content: block.text, partial: output });\n\t\t}\n\t\tstate.textIndex = undefined;\n\t}\n\tfor (const [, entry] of state.toolCalls) {\n\t\tconst block = output.content[entry.contentIndex];\n\t\tif (block?.type === \"toolCall\") {\n\t\t\tevents.push({ type: \"toolcall_end\", contentIndex: entry.contentIndex, toolCall: block, partial: output });\n\t\t}\n\t}\n\tstate.toolCalls.clear();\n}\n\nasync function detail(response: Response): Promise<string> {\n\ttry {\n\t\tconst body = await response.text();\n\t\treturn body ? `: ${body.slice(0, 500)}` : \"\";\n\t} catch {\n\t\treturn \"\";\n\t}\n}\n\nfunction messageOf(error: unknown): string {\n\tif (error instanceof Error) return error.message;\n\treturn String(error);\n}\n"]}
@@ -709,7 +709,10 @@ function buildToolResultText(text, hasImages, supportsImages, isError) {
709
709
  return isError ? "[tool error] (no tool output)" : "(no tool output)";
710
710
  }
711
711
  function usesReasoningEffort(model) {
712
- return model.id === "mistral-small-2603" || model.id === "mistral-small-latest" || model.id === "mistral-medium-3.5";
712
+ return (model.id === "mistral-small-2603" ||
713
+ model.id === "mistral-small-latest" ||
714
+ model.id.startsWith("mistral-medium-") ||
715
+ model.id === "zai-glm-5-2");
713
716
  }
714
717
  function usesPromptModeReasoning(model) {
715
718
  return model.reasoning && !usesReasoningEffort(model);