@illuminis/comprism 0.1.3 → 0.1.4

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 (131) hide show
  1. package/README.md +61 -2
  2. package/out/agent/command.d.ts +75 -4
  3. package/out/agent/command.js +220 -25
  4. package/out/agent/render.d.ts +17 -2
  5. package/out/agent/render.js +157 -14
  6. package/out/agent/session.d.ts +141 -2
  7. package/out/agent/session.js +735 -149
  8. package/out/commands/agents.d.ts +2 -0
  9. package/out/commands/agents.js +79 -0
  10. package/out/commands/ask.d.ts +1 -1
  11. package/out/commands/ask.js +78 -11
  12. package/out/commands/commands-thin.js +79 -17
  13. package/out/commands/config.d.ts +1 -0
  14. package/out/commands/config.js +138 -0
  15. package/out/commands/cost.d.ts +1 -0
  16. package/out/commands/cost.js +167 -0
  17. package/out/commands/hooks.d.ts +1 -0
  18. package/out/commands/hooks.js +83 -0
  19. package/out/commands/install.d.ts +44 -1
  20. package/out/commands/install.js +198 -4
  21. package/out/commands/instructions.d.ts +1 -0
  22. package/out/commands/instructions.js +113 -0
  23. package/out/commands/integrations.d.ts +3 -0
  24. package/out/commands/integrations.js +215 -0
  25. package/out/commands/jobs.d.ts +5 -0
  26. package/out/commands/jobs.js +157 -0
  27. package/out/commands/login.js +188 -36
  28. package/out/commands/memory.d.ts +3 -0
  29. package/out/commands/memory.js +113 -0
  30. package/out/commands/permissions.d.ts +1 -0
  31. package/out/commands/permissions.js +94 -0
  32. package/out/commands/plugins.d.ts +4 -0
  33. package/out/commands/plugins.js +192 -0
  34. package/out/commands/privacy.d.ts +1 -0
  35. package/out/commands/privacy.js +57 -0
  36. package/out/commands/providerKey.d.ts +32 -0
  37. package/out/commands/providerKey.js +108 -0
  38. package/out/commands/repl.d.ts +8 -1
  39. package/out/commands/repl.js +1207 -118
  40. package/out/commands/report.d.ts +39 -0
  41. package/out/commands/report.js +115 -0
  42. package/out/commands/review.d.ts +5 -0
  43. package/out/commands/review.js +223 -0
  44. package/out/commands/sessions.d.ts +23 -0
  45. package/out/commands/sessions.js +115 -0
  46. package/out/commands/settings.d.ts +3 -1
  47. package/out/commands/settings.js +18 -16
  48. package/out/commands/skills.d.ts +21 -0
  49. package/out/commands/skills.js +207 -0
  50. package/out/commands/unattended.d.ts +7 -0
  51. package/out/commands/unattended.js +351 -0
  52. package/out/commands/update.d.ts +1 -0
  53. package/out/commands/update.js +123 -0
  54. package/out/commands/worktrees.d.ts +5 -0
  55. package/out/commands/worktrees.js +186 -0
  56. package/out/executor/browser.d.ts +14 -0
  57. package/out/executor/browser.js +270 -0
  58. package/out/executor/diagnostics.d.ts +2 -0
  59. package/out/executor/diagnostics.js +181 -0
  60. package/out/executor/files.js +270 -40
  61. package/out/executor/git.js +42 -29
  62. package/out/executor/hooks.d.ts +42 -58
  63. package/out/executor/hooks.js +89 -182
  64. package/out/executor/index.d.ts +21 -5
  65. package/out/executor/index.js +160 -14
  66. package/out/executor/paths.d.ts +6 -1
  67. package/out/executor/paths.js +34 -6
  68. package/out/executor/sandbox.d.ts +40 -0
  69. package/out/executor/sandbox.js +299 -0
  70. package/out/executor/shell.d.ts +49 -4
  71. package/out/executor/shell.js +302 -56
  72. package/out/executor/toolservers.d.ts +20 -0
  73. package/out/executor/toolservers.js +189 -0
  74. package/out/executor/worktree.d.ts +9 -0
  75. package/out/executor/worktree.js +119 -0
  76. package/out/graph/read-python.js +2 -1
  77. package/out/lib/attach.d.ts +56 -12
  78. package/out/lib/attach.js +230 -63
  79. package/out/lib/clipboard.d.ts +23 -0
  80. package/out/lib/clipboard.js +182 -0
  81. package/out/lib/commandlist.d.ts +20 -0
  82. package/out/lib/commandlist.js +58 -0
  83. package/out/lib/decision.d.ts +22 -0
  84. package/out/lib/decision.js +50 -0
  85. package/out/lib/fingerprint.d.ts +25 -0
  86. package/out/lib/fingerprint.js +58 -0
  87. package/out/lib/gateway.d.ts +186 -2
  88. package/out/lib/gateway.js +59 -4
  89. package/out/lib/history.d.ts +24 -0
  90. package/out/lib/history.js +137 -0
  91. package/out/lib/ide.d.ts +19 -0
  92. package/out/lib/ide.js +131 -0
  93. package/out/lib/keyboard.d.ts +95 -0
  94. package/out/lib/keyboard.js +383 -0
  95. package/out/lib/machine.d.ts +21 -0
  96. package/out/lib/machine.js +91 -0
  97. package/out/lib/notify.d.ts +4 -0
  98. package/out/lib/notify.js +52 -0
  99. package/out/lib/output.d.ts +48 -0
  100. package/out/lib/output.js +108 -0
  101. package/out/lib/project-ops.d.ts +19 -0
  102. package/out/lib/project-ops.js +146 -0
  103. package/out/lib/project.d.ts +28 -0
  104. package/out/lib/project.js +114 -0
  105. package/out/lib/prompt.js +15 -2
  106. package/out/lib/queue.d.ts +13 -0
  107. package/out/lib/queue.js +116 -0
  108. package/out/lib/readiness.d.ts +19 -0
  109. package/out/lib/readiness.js +170 -1
  110. package/out/lib/self.d.ts +23 -0
  111. package/out/lib/self.js +124 -0
  112. package/out/lib/sessions.d.ts +19 -0
  113. package/out/lib/sessions.js +221 -0
  114. package/out/lib/stdin.d.ts +32 -0
  115. package/out/lib/stdin.js +117 -0
  116. package/out/lib/store.d.ts +40 -0
  117. package/out/lib/store.js +138 -0
  118. package/out/lib/sync.d.ts +18 -0
  119. package/out/lib/sync.js +81 -0
  120. package/out/lib/ui.d.ts +2 -4
  121. package/out/lib/ui.js +31 -25
  122. package/out/lib/voice.js +24 -0
  123. package/out/postinstall.js +42 -17
  124. package/out/providers/anthropic.d.ts +22 -0
  125. package/out/providers/anthropic.js +80 -0
  126. package/out/providers/index.d.ts +8 -0
  127. package/out/providers/index.js +83 -0
  128. package/out/providers/openai.d.ts +11 -0
  129. package/out/providers/openai.js +57 -0
  130. package/out/thin.js +594 -32
  131. package/package.json +9 -49
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProviderHttpError = void 0;
4
+ exports.callAnthropic = callAnthropic;
5
+ const DEFAULT_BASE = 'https://api.anthropic.com';
6
+ const API_VERSION = '2023-06-01';
7
+ /**
8
+ * Honor the same base-URL override every client in this ecosystem supports.
9
+ *
10
+ * It is the mechanism our own proxy is installed with, so the Companion's SDK
11
+ * respecting it is not a test hook: it is what lets one instrumented tool sit
12
+ * behind another, and what lets a customer point us at a gateway they already
13
+ * run.
14
+ */
15
+ function endpoint() {
16
+ const base = (process.env.ANTHROPIC_BASE_URL || DEFAULT_BASE).replace(/\/+$/, '');
17
+ return `${base}/v1/messages`;
18
+ }
19
+ async function callAnthropic(call) {
20
+ const started = Date.now();
21
+ const res = await fetch(endpoint(), {
22
+ method: 'POST',
23
+ headers: {
24
+ 'content-type': 'application/json',
25
+ 'x-api-key': call.apiKey,
26
+ 'anthropic-version': API_VERSION,
27
+ },
28
+ body: JSON.stringify({
29
+ model: call.model,
30
+ max_tokens: call.maxTokens,
31
+ messages: call.messages.map((m) => ({ role: m.role, content: m.content })),
32
+ }),
33
+ });
34
+ const latencyMs = Date.now() - started;
35
+ if (!res.ok) {
36
+ // The status line, never the body: a provider error body can echo the
37
+ // request, and the request is the customer's content.
38
+ const err = new ProviderHttpError(res.status, `anthropic ${res.status} ${res.statusText}`);
39
+ err.latencyMs = latencyMs;
40
+ throw err;
41
+ }
42
+ const body = (await res.json());
43
+ const blocks = body.content || [];
44
+ const text = blocks
45
+ .filter((b) => b.type === 'text' && typeof b.text === 'string')
46
+ .map((b) => b.text)
47
+ .join('');
48
+ // A model that thinks by default and is given a tight token ceiling spends the
49
+ // ceiling on thinking and answers with nothing. That returns as an empty
50
+ // string, which is indistinguishable from a bad answer - and it cost a real
51
+ // bake-off run before it was caught. Name it instead of hiding it.
52
+ const thoughtButDidNotAnswer = text.length === 0 && blocks.some((b) => b.type === 'thinking' || b.type === 'redacted_thinking');
53
+ const usage = {
54
+ inputTokens: typeof body.usage?.input_tokens === 'number' ? body.usage.input_tokens : null,
55
+ outputTokens: typeof body.usage?.output_tokens === 'number' ? body.usage.output_tokens : null,
56
+ };
57
+ return {
58
+ text,
59
+ usage,
60
+ finishReason: thoughtButDidNotAnswer ? 'thinking_exhausted_budget' : body.stop_reason || 'end_turn',
61
+ latencyMs,
62
+ usageReported: usage.inputTokens !== null && usage.outputTokens !== null,
63
+ ...(thoughtButDidNotAnswer
64
+ ? {
65
+ errorMessage: 'the model used its whole token budget thinking and had none left to answer; raise maxTokens',
66
+ }
67
+ : {}),
68
+ };
69
+ }
70
+ /** Carries the status code so the shared retry policy can read it. */
71
+ class ProviderHttpError extends Error {
72
+ status;
73
+ latencyMs = 0;
74
+ constructor(status, message) {
75
+ super(message);
76
+ this.name = 'ProviderHttpError';
77
+ this.status = status;
78
+ }
79
+ }
80
+ exports.ProviderHttpError = ProviderHttpError;
@@ -0,0 +1,8 @@
1
+ import type { Keys } from '../lib/config';
2
+ import type { Provider, ProviderCall, ProviderResult } from '../lib/types';
3
+ export { ProviderHttpError } from './anthropic';
4
+ export declare function providerOf(model: string): Provider | null;
5
+ /**
6
+ * Dispatch one call. Returns a result in every case, including failure.
7
+ */
8
+ export declare function callModel(call: ProviderCall, keys: Keys): Promise<ProviderResult>;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProviderHttpError = void 0;
4
+ exports.providerOf = providerOf;
5
+ exports.callModel = callModel;
6
+ /**
7
+ * One normalized call interface across every provider.
8
+ *
9
+ * Two properties matter to everything downstream:
10
+ *
11
+ * 1. `callModel` never throws out of `send()`. A provider error becomes
12
+ * `finishReason: 'error'` with an empty body, so the ledger still gets its
13
+ * row and the client still records what happened. Rule 10, fail open: the
14
+ * product being unable to reach a provider must look like a recorded
15
+ * failure, not like a crash in someone's editor.
16
+ * 2. One retry on 429 and 5xx with jitter, then surface. A second retry buys
17
+ * little and doubles the worst-case wait a person is sitting through.
18
+ */
19
+ const catalog_1 = require("../internal/catalog");
20
+ const anthropic_1 = require("./anthropic");
21
+ const openai_1 = require("./openai");
22
+ var anthropic_2 = require("./anthropic");
23
+ Object.defineProperty(exports, "ProviderHttpError", { enumerable: true, get: function () { return anthropic_2.ProviderHttpError; } });
24
+ const DEFAULT_MAX_TOKENS = 4096;
25
+ const RETRY_BASE_MS = 400;
26
+ function isRetryable(err) {
27
+ if (err instanceof anthropic_1.ProviderHttpError)
28
+ return err.status === 429 || err.status >= 500;
29
+ // A transport failure - DNS, reset connection, timeout - is worth one retry.
30
+ return err instanceof TypeError;
31
+ }
32
+ function jitteredDelay() {
33
+ return RETRY_BASE_MS + Math.floor(Math.random() * RETRY_BASE_MS);
34
+ }
35
+ function sleep(ms) {
36
+ return new Promise((resolve) => setTimeout(resolve, ms));
37
+ }
38
+ function providerOf(model) {
39
+ return (0, catalog_1.findModel)(model)?.provider ?? null;
40
+ }
41
+ /**
42
+ * Dispatch one call. Returns a result in every case, including failure.
43
+ */
44
+ async function callModel(call, keys) {
45
+ const provider = providerOf(call.model);
46
+ if (!provider) {
47
+ return errorResult(`unknown model: ${call.model}`, 0);
48
+ }
49
+ const apiKey = keys[provider];
50
+ if (!apiKey) {
51
+ return errorResult(`no key resolved for ${provider}`, 0);
52
+ }
53
+ const maxTokens = call.maxTokens ?? DEFAULT_MAX_TOKENS;
54
+ const args = { model: call.model, messages: call.messages, maxTokens, apiKey };
55
+ for (let attempt = 0; attempt < 2; attempt++) {
56
+ try {
57
+ return provider === 'anthropic' ? await (0, anthropic_1.callAnthropic)(args) : await (0, openai_1.callOpenAi)(args);
58
+ }
59
+ catch (err) {
60
+ if (attempt === 0 && isRetryable(err)) {
61
+ await sleep(jitteredDelay());
62
+ continue;
63
+ }
64
+ const latency = err instanceof anthropic_1.ProviderHttpError ? err.latencyMs : 0;
65
+ return errorResult(err instanceof Error ? err.message : 'provider call failed', latency);
66
+ }
67
+ }
68
+ return errorResult('provider call failed', 0);
69
+ }
70
+ /**
71
+ * The failure shape. The message is a status line or a transport error - never
72
+ * a response body, which can contain the request that produced it.
73
+ */
74
+ function errorResult(message, latencyMs) {
75
+ return {
76
+ text: '',
77
+ usage: { inputTokens: null, outputTokens: null },
78
+ finishReason: 'error',
79
+ latencyMs,
80
+ usageReported: false,
81
+ errorMessage: message,
82
+ };
83
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * OpenAI adapter. Same shape as the Anthropic one, same dependency-free stance.
3
+ */
4
+ import type { Message, ProviderResult } from '../lib/types';
5
+ export interface OpenAiCall {
6
+ model: string;
7
+ messages: Message[];
8
+ maxTokens: number;
9
+ apiKey: string;
10
+ }
11
+ export declare function callOpenAi(call: OpenAiCall): Promise<ProviderResult>;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.callOpenAi = callOpenAi;
4
+ const anthropic_1 = require("./anthropic");
5
+ const DEFAULT_BASE = 'https://api.openai.com/v1';
6
+ /** Same base-URL override every OpenAI-compatible client already supports. */
7
+ function endpoint() {
8
+ const base = (process.env.OPENAI_BASE_URL || DEFAULT_BASE).replace(/\/+$/, '');
9
+ return `${base}/chat/completions`;
10
+ }
11
+ /**
12
+ * The reasoning-model families take `max_completion_tokens`; the older chat
13
+ * families take `max_tokens`. Sending the wrong one is a 400, so the choice is
14
+ * made from the model id rather than left to the caller.
15
+ */
16
+ function tokenLimitField(model) {
17
+ return /^gpt-4/.test(model) ? 'max_tokens' : 'max_completion_tokens';
18
+ }
19
+ async function callOpenAi(call) {
20
+ const started = Date.now();
21
+ const body = {
22
+ model: call.model,
23
+ messages: call.messages.map((m) => ({ role: m.role, content: m.content })),
24
+ };
25
+ body[tokenLimitField(call.model)] = call.maxTokens;
26
+ const res = await fetch(endpoint(), {
27
+ method: 'POST',
28
+ headers: {
29
+ 'content-type': 'application/json',
30
+ authorization: `Bearer ${call.apiKey}`,
31
+ },
32
+ body: JSON.stringify(body),
33
+ });
34
+ const latencyMs = Date.now() - started;
35
+ if (!res.ok) {
36
+ const err = new anthropic_1.ProviderHttpError(res.status, `openai ${res.status} ${res.statusText}`);
37
+ err.latencyMs = latencyMs;
38
+ throw err;
39
+ }
40
+ const parsed = (await res.json());
41
+ const choice = parsed.choices?.[0];
42
+ const text = choice?.message?.content || '';
43
+ const usage = {
44
+ inputTokens: typeof parsed.usage?.prompt_tokens === 'number' ? parsed.usage.prompt_tokens : null,
45
+ outputTokens: typeof parsed.usage?.completion_tokens === 'number' ? parsed.usage.completion_tokens : null,
46
+ reasoningTokens: typeof parsed.usage?.completion_tokens_details?.reasoning_tokens === 'number'
47
+ ? parsed.usage.completion_tokens_details.reasoning_tokens
48
+ : null,
49
+ };
50
+ return {
51
+ text,
52
+ usage,
53
+ finishReason: choice?.finish_reason || 'stop',
54
+ latencyMs,
55
+ usageReported: usage.inputTokens !== null && usage.outputTokens !== null,
56
+ };
57
+ }