Skip to content

Conversation

@roomote
Copy link
Contributor

@roomote roomote bot commented Sep 26, 2025

This PR introduces a minimal LaminarService wrapper and wires basic task.step span start/end around user messages and attempt_completion.\n\nChanges:\n- Added LaminarService (safe no-op wrapper with future SDK hook) at src/services/laminar/LaminarService.ts\n- Start span in Task.submitUserMessage() and end in attemptCompletionTool()\n- Add type shim src/types/lmnr.d.ts to avoid missing module type error\n- Tests pass: cd src && npx vitest run\n- Lint passes: pnpm run lint\n\nThis is groundwork pending clarification for full port of cline/cline#5862.

- Introduce LaminarService (lightweight, no-op if disabled)\n- Start span in Task.submitUserMessage() and end in attemptCompletionTool()\n- Add types shim at src/types/lmnr.d.ts to avoid missing module types\n- Tests pass (cd src && npx vitest run)\n- Lint passes (pnpm run lint)\n\nNote: groundwork for porting cline/cline#5862; pending clarification on full scope.
@vercel
Copy link

vercel bot commented Sep 26, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
roo-code-website Error Error Sep 26, 2025 7:08am

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Sep 26, 2025
Copy link
Contributor Author

@roomote roomote bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self-review: judging my own code — impartiality module returned 404.

* Safe no-op when disabled; still returns an id for balanced calls.
*/
public startSpan(name: string, attributes: Attributes = {}): string {
const id = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Not a true no-op when disabled. startSpan/endSpan record spans and debugSpan logs even if initialize() never enables tracing. Gate behavior behind enabled (bail early in startSpan/endSpan; guard debug/debugSpan) to avoid console noise and memory overhead.

// Try to dynamically load the SDK if enabled
if (this.enabled) {
try {
const mod = await import("@lmnr-ai/lmnr")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Dynamic import likely needs default handling. If the SDK exports default, future calls like this.sdk.init may fail. Normalize the module:

Suggested change
const mod = await import("@lmnr-ai/lmnr")
const mod = await import("@lmnr-ai/lmnr");
this.sdk = (mod as any).default ?? mod;


// End current task.step span if active
try {
if ((cline as any).laminarSpanId) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Accessing a private field via (cline as any).laminarSpanId bypasses types and couples modules. Prefer a Task instance method to end the active span (or encapsulate span lifecycle within Task).


// Start a tracing span for this user turn
try {
this.laminarSpanId = laminar.startSpan("task.step", { taskId: this.taskId })
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Span starts here but ends in attemptCompletionTool. If control flow exits early or errors differently, spans can remain open. Consider centralizing lifecycle in Task (e.g., try/finally) or using a Task event hook to end the span reliably.


// Simple in-memory span store and active stack
private spans = new Map<string, InternalSpan>()
private activeStack: string[] = []
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: activeStack is process-global; concurrent tasks may interleave and corrupt parent/child relationships. Use AsyncLocalStorage for per-async-context stacks or maintain stacks keyed by sessionId/taskId.

private debug(msg: string) {
// Keep logs minimal to avoid noise
try {
console.log(msg)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: console.log in debug() adds noise and may violate lint rules. Prefer console.debug or a central logger, and gate logs behind an opt-in debug flag and/or enabled.

@@ -0,0 +1,4 @@
declare module "@lmnr-ai/lmnr" {
const mod: any
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Type shim assumes a default export; if the SDK migrates to named exports this could mislead consumers. Consider exporting both default and named to keep flexibility.

@daniel-lxs daniel-lxs moved this from Triage to PR [Draft / In Progress] in Roo Code Roadmap Oct 14, 2025
@hannesrudolph hannesrudolph added PR - Draft / In Progress and removed Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. labels Oct 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: PR [Draft / In Progress]

Development

Successfully merging this pull request may close these issues.

3 participants