feat: update supercode-cli version to 0.1.73 and enhance AI provider functionality:#213
Conversation
…functionality: - Bumped version in package.json to 0.1.73. - Introduced new "supercode" model provider with enhanced API integration for chat and task generation. - Added support for user interaction through new question and todo management tools. - Improved permission management by adding new permissions for question handling.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
WalkthroughSupercode provider routing now supports streaming chat and structured generation. The CLI also adds interactive question and session-scoped todo tools, including schemas, rendering, registry entries, and permission defaults. ChangesSupercode AI integration
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant CLI
participant ServerProxyService
participant AIChatHandler
participant ConcentrateAI
CLI->>ServerProxyService: Submit Supercode chat request
ServerProxyService->>AIChatHandler: Forward as concentrateai
AIChatHandler->>ConcentrateAI: Request streaming completion
ConcentrateAI-->>AIChatHandler: Stream text and tool-call deltas
AIChatHandler-->>CLI: Emit response events or fallback content
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (1)
apps/supercode-cli/server/src/index.ts (1)
817-817: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueAlign the new early returns with the TypeScript style rules.
Expand these blocks and remove the statement-ending semicolons. As per coding guidelines,
**/*.{ts,tsx,js,mjs,cjs}must not use semicolons at the end of statements.Also applies to: 855-855, 1086-1086
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/supercode-cli/server/src/index.ts` at line 817, Update the early-return blocks around the apiKey checks and the corresponding locations near lines 855 and 1086 to use expanded multi-line blocks, and remove statement-ending semicolons from the response and return statements to comply with the TypeScript style rules.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/supercode-cli/server/src/index.ts`:
- Around line 913-945: The fallback request in the empty-content path must
preserve tools and propagate upstream failures. Update the fallback body
construction around fbBody to reuse the original bodyObj fields, including
tools, while retaining the fallback-specific messages and settings; when fbRes
is not successful, return the upstream error response instead of continuing as
an empty successful completion.
- Around line 1091-1105: Update the Supercode provider branch around the
response handling to honor the requested schema: parse the model’s structured
response using the existing schema-driven path and return the resulting object
instead of wrapping free-form message.content in object.content. Preserve the
current HTTP error handling and use the same structured-generation utilities or
response shape as the other provider branches.
- Around line 831-833: Update the streamed request configuration near
getModelMaxTokens to include usage metadata via stream_options. Propagate cached
prompt-token counts through recordUsage and computeCost, then populate emitted
inputTokenDetails with the resulting values so streamed runs persist accurate
token and cost totals.
In `@apps/supercode-cli/server/src/tools/definitions/question.ts`:
- Around line 100-126: The selection handling around rl.question must re-prompt
until valid input is entered. Validate the complete trimmed input rather than
accepting parseInt prefixes; for single-choice input reject blanks, malformed,
and out-of-range values, and for multiple-choice input reject invalid entries
instead of resolving an empty result. Preserve valid option-label resolution
while routing every invalid selection back through the prompt.
In `@apps/supercode-cli/server/src/tools/definitions/todowrite.ts`:
- Around line 13-25: Replace the process-wide currentTodos state used by
setTodos, getTodos, and clearTodos with session-scoped storage, either on the
session/agent context or keyed by a stable session identifier. Ensure each
method reads and updates only the current session’s todo list while preserving
defensive copying of TodoItem values.
- Around line 78-86: Update todowriteSchema to validate that the todos array
contains at most one item with status "in_progress", rejecting invalid lists
before state updates occur. Keep the existing minimum-length and todo item
validation unchanged, and preserve the documented single-active-todo behavior
used by the surrounding todo-write flow.
---
Nitpick comments:
In `@apps/supercode-cli/server/src/index.ts`:
- Line 817: Update the early-return blocks around the apiKey checks and the
corresponding locations near lines 855 and 1086 to use expanded multi-line
blocks, and remove statement-ending semicolons from the response and return
statements to comply with the TypeScript style rules.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 74686e3e-c637-4ed4-b4eb-1a25c6b59162
📒 Files selected for processing (7)
apps/supercode-cli/server/package.jsonapps/supercode-cli/server/src/cli/ai/provider.tsapps/supercode-cli/server/src/index.tsapps/supercode-cli/server/src/tools/definitions/question.tsapps/supercode-cli/server/src/tools/definitions/todowrite.tsapps/supercode-cli/server/src/tools/permission-manager.tsapps/supercode-cli/server/src/tools/registry.ts
| max_tokens: getModelMaxTokens(modelName), | ||
| temperature: 0.7, | ||
| stream: true, |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="apps/supercode-cli/server/src/index.ts"
echo "== file size =="
wc -l "$FILE"
echo
echo "== relevant lines around 800-980 =="
sed -n '800,980p' "$FILE" | cat -n
echo
echo "== search for accounting helpers =="
rg -n "recordUsage|computeCost|inputTokenDetails|cached_tokens|stream_options|include_usage|usage" "$FILE"Repository: yashdev9274/supercli
Length of output: 13524
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="apps/supercode-cli/server/src/index.ts"
echo "== stream request blocks =="
sed -n '820,970p' "$FILE" | nl -ba | sed -n '1,220p'
echo
echo "== definitions and usages =="
rg -n -C 3 "recordUsage|computeCost|inputTokenDetails|cached_tokens|prompt_tokens_details|completion_tokens_details|usage event|stream_options|include_usage" "$FILE"Repository: yashdev9274/supercli
Length of output: 226
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -C 2 "stream_options|include_usage|prompt_tokens_details|cached_tokens|recordUsage|computeCost|inputTokenDetails" apps/supercode-cli/server/srcRepository: yashdev9274/supercli
Length of output: 34747
🌐 Web query:
OpenAI Chat Completions streaming include_usage prompt_tokens_details.cached_tokens usage event docs
💡 Result:
To include token usage statistics in your OpenAI Chat Completions streaming response, you must set the stream_options parameter to {"include_usage": true} in your request [1][2][3]. When this option is enabled: 1. Every streaming chunk will contain a usage field, which is set to null for all chunks except the final one [4][1][3]. 2. An additional, final chunk is streamed before the data: [DONE] message [4][2][3]. This final chunk contains the total token usage statistics for the entire request in its usage field [4][1][2]. 3. The choices array in this final usage-only chunk will be empty [4][1][2]. Regarding prompt_tokens_details and cached_tokens: When usage statistics are included, the usage object may contain a prompt_tokens_details field, which provides a breakdown of tokens used in the prompt [5]. This includes the cached_tokens field, which indicates how many input tokens were read from cache [5]. If prompt caching is not applicable or the request is small (typically under 1024 tokens), cached_tokens is zero [5][6]. The structure and presence of these fields in the final streaming usage chunk follow the same schema as non-streaming response usage objects [5]. Note: If the stream is interrupted, you may not receive this final usage chunk [4][2]. Additionally, ensure your code handles the final usage chunk by checking for the presence of usage data and an empty choices array, as this differs from standard content chunks [1][3].
Citations:
- 1: https://community.openai.com/t/usage-stats-now-available-when-using-streaming-with-the-chat-completions-api-or-completions-api/738156/1
- 2: https://developers.openai.com/api/reference/resources/completions/methods/create
- 3: https://community.openai.com/t/usage-stats-now-available-when-using-streaming-with-the-chat-completions-api-or-completions-api/738156
- 4: https://fossies.org/linux/openai-python/src/openai/types/chat/chat_completion_stream_options_param.py
- 5: https://developers.openai.com/api/docs/guides/prompt-caching
- 6: usage.prompt_tokens_details=None openai/openai-python#2544
Request streamed usage metadata.
Add stream_options: { include_usage: true } to the streamed request, and carry cached prompt-token counts through recordUsage, computeCost, and the emitted inputTokenDetails; otherwise streamed runs persist zero/incorrect token and cost totals.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/supercode-cli/server/src/index.ts` around lines 831 - 833, Update the
streamed request configuration near getModelMaxTokens to include usage metadata
via stream_options. Propagate cached prompt-token counts through recordUsage and
computeCost, then populate emitted inputTokenDetails with the resulting values
so streamed runs persist accurate token and cost totals.
| if (!fullContent.trim() && !sawToolCalls) { | ||
| const fbBody: any = { | ||
| model: modelName, | ||
| messages: nonSystemMessages.map((m: any) => { | ||
| const msg: any = { | ||
| role: m.role, | ||
| content: m.content !== null && m.content !== undefined ? String(m.content) : "", | ||
| } | ||
| if (m.tool_calls) msg.tool_calls = m.tool_calls | ||
| if (m.tool_call_id) msg.tool_call_id = m.tool_call_id | ||
| return msg | ||
| }), | ||
| max_tokens: getModelMaxTokens(modelName), | ||
| temperature: 0.7, | ||
| stream: false, | ||
| } | ||
| if (system && nonSystemMessages.length > 0) { | ||
| fbBody.messages = [{ role: "system", content: system }, ...fbBody.messages] | ||
| } | ||
| const fbRes = await fetch("https://api.concentrate.ai/v1/chat/completions", { | ||
| method: "POST", | ||
| headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" }, | ||
| body: JSON.stringify(fbBody), | ||
| }) | ||
| if (fbRes.ok) { | ||
| const fbData: any = await fbRes.json() | ||
| const fbContent = fbData?.choices?.[0]?.message?.content ?? "" | ||
| if (fbContent) { | ||
| res.write(JSON.stringify({ type: "text", content: fbContent }) + "\n") | ||
| } | ||
| inputTokens = fbData?.usage?.prompt_tokens ?? 0 | ||
| outputTokens = fbData?.usage?.completion_tokens ?? 0 | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Preserve tools and propagate fallback failures.
The fallback drops bodyObj.tools, and a non-2xx fbRes falls through to an empty successful completion. Reuse the original request body and handle fallback errors.
Proposed fix
- const fbBody: any = {
- model: modelName,
- messages: nonSystemMessages.map(/* ... */),
- max_tokens: getModelMaxTokens(modelName),
- temperature: 0.7,
- stream: false,
- }
+ const fbBody = {
+ ...bodyObj,
+ stream: false,
+ }Also return the fallback upstream error when !fbRes.ok.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/supercode-cli/server/src/index.ts` around lines 913 - 945, The fallback
request in the empty-content path must preserve tools and propagate upstream
failures. Update the fallback body construction around fbBody to reuse the
original bodyObj fields, including tools, while retaining the fallback-specific
messages and settings; when fbRes is not successful, return the upstream error
response instead of continuing as an empty successful completion.
| body: JSON.stringify({ | ||
| model: modelName, | ||
| messages: [{ role: "user", content: prompt }], | ||
| max_tokens: getModelMaxTokens(modelName), | ||
| temperature: 0.7, | ||
| stream: false, | ||
| }), | ||
| }) | ||
| if (!response.ok) { | ||
| const errText = await response.text().catch(() => "unknown error") | ||
| res.status(response.status).json({ error: `Supercode Cloud API ${response.status}: ${errText}` }) | ||
| return | ||
| } | ||
| const data: any = await response.json() | ||
| res.json({ object: { content: data.choices?.[0]?.message?.content || "" } }) |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="apps/supercode-cli/server/src/index.ts"
echo "== line count =="
wc -l "$FILE"
echo
echo "== outline (if available) =="
ast-grep outline "$FILE" --view expanded || true
echo
echo "== surrounding lines 1040-1135 =="
sed -n '1040,1135p' "$FILE"
echo
echo "== search for schema usage in file =="
rg -n '\bschema\b|response_format|structured|json_schema|json_object' "$FILE"Repository: yashdev9274/supercli
Length of output: 5247
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find the route/function that contains the snippet and inspect nearby context
FILE="apps/supercode-cli/server/src/index.ts"
python3 - <<'PY'
from pathlib import Path
p = Path("apps/supercode-cli/server/src/index.ts")
text = p.read_text()
needle = 'res.json({ object: { content: data.choices?.[0]?.message?.content || "" } })'
idx = text.find(needle)
print("needle_index", idx)
if idx != -1:
start = max(0, text.rfind('\n', 0, idx - 1500))
end = min(len(text), idx + 700)
snippet = text[start:end]
# show with line numbers
base_line = text[:start].count('\n') + 1
for i, line in enumerate(snippet.splitlines(), start=base_line):
print(f"{i}: {line}")
PYRepository: yashdev9274/supercli
Length of output: 2656
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect whether the API client or downstream parser expects a structured object
rg -n 'object\.content|structured generation|schema-based|response_format|message\.content|choices\?\.\[0\]\?\.message' apps/supercode-cli/server/srcRepository: yashdev9274/supercli
Length of output: 1340
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="apps/supercode-cli/server/src/index.ts"
sed -n '1000,1135p' "$FILE"Repository: yashdev9274/supercli
Length of output: 6066
Use the schema-driven path for the Supercode provider
apps/supercode-cli/server/src/index.ts:1091-1105 — This branch ignores schema and returns free-form message.content under object.content, so structured-generation callers don’t get the object they requested. Match the other structured-generation branches and return the parsed object.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/supercode-cli/server/src/index.ts` around lines 1091 - 1105, Update the
Supercode provider branch around the response handling to honor the requested
schema: parse the model’s structured response using the existing schema-driven
path and return the resulting object instead of wrapping free-form
message.content in object.content. Preserve the current HTTP error handling and
use the same structured-generation utilities or response shape as the other
provider branches.
| rl.question(promptText, (raw) => { | ||
| rl.close() | ||
| if (stdin.isTTY && wasRaw) stdin.setRawMode(true) | ||
|
|
||
| const trimmed = raw.trim() | ||
| if (!trimmed) { | ||
| resolve([]) | ||
| return | ||
| } | ||
|
|
||
| if (item.multiple) { | ||
| const indices = trimmed | ||
| .split(",") | ||
| .map((s) => parseInt(s.trim(), 10)) | ||
| .filter((n) => !isNaN(n) && n >= 1 && n <= item.options!.length) | ||
| if (indices.length === 0) { | ||
| resolve([]) | ||
| return | ||
| } | ||
| resolve(indices.map((i) => item.options![i - 1].label)) | ||
| } else { | ||
| const num = parseInt(trimmed, 10) | ||
| if (isNaN(num) || num < 1 || num > item.options.length) { | ||
| resolve("(invalid selection)") | ||
| return | ||
| } | ||
| resolve(item.options[num - 1].label) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Re-prompt until a valid choice is entered.
parseInt("1x", 10) selects option 1, blank single-choice input resolves [], and out-of-range input completes with "(invalid selection)". Validate the entire input and re-prompt instead of finalizing an unintended answer.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/supercode-cli/server/src/tools/definitions/question.ts` around lines 100
- 126, The selection handling around rl.question must re-prompt until valid
input is entered. Validate the complete trimmed input rather than accepting
parseInt prefixes; for single-choice input reject blanks, malformed, and
out-of-range values, and for multiple-choice input reject invalid entries
instead of resolving an empty result. Preserve valid option-label resolution
while routing every invalid selection back through the prompt.
| let currentTodos: TodoItem[] = [] | ||
|
|
||
| export function setTodos(todos: TodoItem[]): TodoItem[] { | ||
| currentTodos = todos.map((t) => ({ ...t })) | ||
| return getTodos() | ||
| } | ||
|
|
||
| export function getTodos(): TodoItem[] { | ||
| return currentTodos.map((t) => ({ ...t })) | ||
| } | ||
|
|
||
| export function clearTodos(): void { | ||
| currentTodos = [] |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
Scope todo state to the current session.
currentTodos is process-wide, so concurrent sessions overwrite and can read each other’s task lists. Store this state on the session/agent context, or key it by a stable session identifier.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/supercode-cli/server/src/tools/definitions/todowrite.ts` around lines 13
- 25, Replace the process-wide currentTodos state used by setTodos, getTodos,
and clearTodos with session-scoped storage, either on the session/agent context
or keyed by a stable session identifier. Ensure each method reads and updates
only the current session’s todo list while preserving defensive copying of
TodoItem values.
| const todowriteSchema = z.object({ | ||
| todos: z | ||
| .array(todoItemSchema) | ||
| .min(1) | ||
| .describe( | ||
| "The updated todo list for the session. Each item has content, status, and priority. " + | ||
| "Only one item should be 'in_progress' at a time.", | ||
| ), | ||
| }) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Enforce the single in_progress invariant.
The schema only describes this constraint, so multiple active todos are accepted. That makes Lines 62 and 115 disagree about the effective active task. Reject lists containing more than one in_progress item before updating state.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/supercode-cli/server/src/tools/definitions/todowrite.ts` around lines 78
- 86, Update todowriteSchema to validate that the todos array contains at most
one item with status "in_progress", rejecting invalid lists before state updates
occur. Keep the existing minimum-length and todo item validation unchanged, and
preserve the documented single-active-todo behavior used by the surrounding
todo-write flow.
Description
Type of change
How Has This Been Tested?
Please describe the tests that you ran to verify your changes.
bun testpassesbun run typecheckpassesbun run lintpasses (if applicable)Checklist:
Summary by CodeRabbit
New Features
Bug Fixes
Chores