Skip to content

Code smell remediation - #1

Merged
CraftsMan-Labs merged 6 commits into
mainfrom
code-smell-remediation
Apr 2, 2026
Merged

Code smell remediation#1
CraftsMan-Labs merged 6 commits into
mainfrom
code-smell-remediation

Conversation

@CraftsMan-Labs

@CraftsMan-Labs CraftsMan-Labs commented Apr 2, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

Release Notes

  • New Features

    • Added typed response structures across Go, Python, and Node SDKs for runtime activation, invoke results, and chat sessions.
    • Introduced new methods for normalized result handling and improved telemetry event processing.
  • Documentation

    • Added comprehensive shared SDK integration guide covering authentication, environment variables, and common workflows.
    • Updated language-specific integration guides to reference shared documentation.
  • Tests

    • Added contract-driven tests validating telemetry envelope and registration path handling.
  • Chores

    • Added repository hygiene workflow to prevent tracking generated artifacts.
    • Improved build cleanup tooling.

@coderabbitai

coderabbitai Bot commented Apr 2, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR consolidates duplicated SDK integration patterns across Go, Python, and Node by introducing shared typed response models, normalization helpers, and contract fixtures. It refactors HTTP client logic, adds repository hygiene guardrails via CI workflows and cleanup targets, and establishes a structured code-smell remediation roadmap with planning documents.

Changes

Cohort / File(s) Summary
Repository Hygiene & Configuration
.github/workflows/repo-hygiene.yml, .gitignore, CNAME, Makefile, README.md
Added CI workflow to detect tracked generated artifacts (node_modules/, dist/, build/, Python cache), added .gitignore entries for deps/caches, removed custom domain CNAME, introduced make clean target for artifact cleanup, documented new features in README.
Documentation & Planning
docs/index.md, docs/sdk-integration-common.md, docs/sdk-go-integration.md, docs/sdk-node-integration.md, docs/sdk-python-integration.md, code-review/code_smell_*
Consolidated auth/env documentation into shared sdk-integration-common.md guide (machine auth, user auth, OAuth, environment variables, integration sequence); refactored language-specific guides to reference shared content; added comprehensive code-smell report and multi-phase remediation technical/execution plans.
Shared Contracts & Fixtures
contracts/telemetry-envelope-v1/workflow_basic.json, contracts/runtime-registration/action_path_cases.json
Added telemetry envelope v1 contract fixture with workflow events, trace/tenant metadata, and expected payload schema; added runtime registration action path test cases for URL template substitution validation.
Go SDK: Typed Response Models & Refactoring
go/simpleflow/response_models.go, go/simpleflow/client.go, go/simpleflow/client_test.go
Introduced typed data structures (TelemetryEnvelopeV1, RuntimeActivationResult, ChatSession, etc.); refactored WriteEventFromWorkflowResult to extract context resolution into resolveWorkflowEventContext helper; consolidated HTTP request logic via new doJSON helper supporting POST/PATCH/GET; enhanced stringAny type converter; added contract-driven fixture tests.
Python SDK: Typed Response Models & Refactoring
python/simpleflow_sdk/response_models.py, python/simpleflow_sdk/__init__.py, python/simpleflow_sdk/client.py, python/tests/test_client.py
Introduced TypedDict-based response schemas; added invoke_typed(), list_chat_sessions_typed(), and ensure_runtime_registration_active_typed() methods; extracted normalization helpers (_normalize_runtime_activation_result(), etc.) and context resolution (_resolve_workflow_event_context()); consolidated HTTP logic with _request_json() helper; added test fixtures and helper for consistent client setup.
Node SDK: Typed Methods & Normalization
node/simpleflow_sdk/index.js, node/simpleflow_sdk/tests/client.test.js
Added typed methods invokeTyped() and listChatSessionsTyped() with normalized response shapes; extracted workflow context resolution (_resolveWorkflowEventContext()) and active-registration logic; introduced allowlists for event/message key filtering; added fixture-driven tests for telemetry envelope and action path validation.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Poem

🐰 Three SDKs unified, their types now clear,
Contracts blossom like clover blooming here,
The repo breathes clean with hygiene so bright,
Normalize, consolidate—refactor's delight! ✨🌿

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Code smell remediation' directly summarizes the main objective of this changeset, which is a comprehensive remediation effort addressing multiple code smells across the Go, Python, and Node SDKs through refactoring, documentation, and repository hygiene improvements.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch code-smell-remediation

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (4)
python/tests/test_client.py (1)

449-455: Prefix unused variable with underscore.

Static analysis correctly flags fake_http as unused. Prefix it to indicate intentional disuse.

     def test_chat_history_list_method(self) -> None:
-        client, fake_http = self._new_client()
+        client, _fake_http = self._new_client()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@python/tests/test_client.py` around lines 449 - 455, The test assigns an
unused variable `fake_http` from _new_client(), causing static analysis
warnings; rename it to `_fake_http` (or prefix with an underscore) in the
`test_chat_history_list_method` so the call stays the same but the linter
recognizes the variable as intentionally unused; update the variable name
wherever it's referenced in that test (here only in the assignment) to
`_fake_http`.
node/simpleflow_sdk/index.js (1)

650-660: Consider simplifying sampledForEvent and sampledForEnvelope.

Both values are computed identically (line 658-659). While separating them provides future flexibility, the Python SDK uses a single sampled value. Consider unifying for cross-SDK consistency.

-    sampledForEvent,
-    sampledForEnvelope: sampledForEvent,
+    sampled: sampledForEvent,

Then update lines 620 and 633 to use context.sampled.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@node/simpleflow_sdk/index.js` around lines 650 - 660, Unify the duplicate
sampling fields by replacing sampledForEvent and sampledForEnvelope with a
single sampled property: compute sampled once (currently computed into
sampledForEvent) using typeof telemetry.sampled === "boolean" ?
telemetry.sampled : true and return it as sampled, then update places that read
context.sampled (previously using sampledForEvent/sampledForEnvelope) —
specifically change the usages in the code that reference sampledForEvent and
sampledForEnvelope (e.g., the callers around the former lines where context is
built and at the two call sites you noted) to read context.sampled so the SDK
matches the Python single-sampled convention.
python/simpleflow_sdk/response_models.py (1)

92-97: Missing trailing newline.

The file should end with a newline for POSIX compliance.

 class ChatSession(TypedDict, total=False):
     chat_id: str
     status: str
     agent_id: str
     user_id: str
     metadata: dict[str, Any]
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@python/simpleflow_sdk/response_models.py` around lines 92 - 97, The file ends
without a POSIX newline; add a single trailing newline at EOF so the ChatSession
TypedDict declaration (class ChatSession) is followed by a newline character.
Ensure the file is saved with a final '\n' after the last line so tools
expecting POSIX-compliant files recognize the newline.
go/simpleflow/client_test.go (1)

333-364: Unchecked type assertions may cause test panics on fixture format changes.

Multiple type assertions (e.g., fixture["expected_event"].(map[string]any), payload["usage"].(map[string]any)) lack safety checks. If the fixture format drifts or a key is missing, the test will panic instead of providing a clear failure message.

🛡️ Suggested defensive approach
-	expectedEvent := fixture["expected_event"].(map[string]any)
+	expectedEvent, ok := fixture["expected_event"].(map[string]any)
+	if !ok {
+		t.Fatalf("expected_event is not a map")
+	}

Apply similar checks for expectedPayload, payload, usage, expectedUsage, and modelUsage assertions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@go/simpleflow/client_test.go` around lines 333 - 364, The test currently uses
unchecked type assertions (e.g., expectedEvent :=
fixture["expected_event"].(map[string]any), payload :=
captured["payload"].(map[string]any), usage :=
payload["usage"].(map[string]any), expectedUsage :=
expectedPayload["usage"].(map[string]any), modelUsage :=
payload["model_usage"].([]any)) which can panic on malformed fixtures; replace
these with safe checks (use the "comma ok" form) and call t.Fatalf with clear
messages when a key is missing or the type is wrong, and for modelUsage validate
it is a []any and has at least one element before accessing [0]; ensure you
check captured["payload"], fixture["expected_payload"], and all nested keys
exist and have expected types (expectedEvent, expectedPayload, payload, usage,
expectedUsage, modelUsage) before comparing values so failures report
descriptive errors instead of panics.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/sdk-integration-common.md`:
- Around line 30-33: The docs currently only list the user bearer env variable
`SIMPLEFLOW_USER_BEARER`; add an explicit API-key env variable entry (e.g.,
`SIMPLEFLOW_API_KEY` or `SIMPLEFLOW_AG_API_KEY`) alongside
`SIMPLEFLOW_USER_BEARER` to show chat accepts agk_* API keys or user bearers;
update the User-scoped APIs section to include that API-key env var name and a
short example note indicating it accepts agk_* keys for chat use cases so
readers aren’t ambiguous about which env var to set.
- Around line 44-45: Update the shared sequence wording to use Python snake_case
method names instead of Node-style names so Python users can copy/paste
directly: replace Node-style references like withTelemetry(...).emitSpan(...)
and writeEventFromWorkflowResult with the Python equivalents
with_telemetry(...).emit_span(...) and write_event_from_workflow_result (or
include both language variants side-by-side). Ensure the same change is applied
to the chat history guidance to mention using a user bearer token with the
language-appropriate API names (e.g., Python snake_case).

In `@Makefile`:
- Around line 68-73: The Makefile's clean target currently removes various build
directories but omits Python bytecode artifacts; update the clean recipe for the
clean target to also remove Python __pycache__ directories and *.pyc files
(e.g., add rm -rf "**/__pycache__" "**/*.pyc" and/or remove __pycache__ and
*.pyc under the python/ and any package dirs referenced by the existing
patterns) so Python bytecode is cleaned alongside python/dist, python/build, and
egg-info; apply the changes within the existing clean target (referencing the
Makefile target name clean) to avoid leaving generated Python artifacts behind.

---

Nitpick comments:
In `@go/simpleflow/client_test.go`:
- Around line 333-364: The test currently uses unchecked type assertions (e.g.,
expectedEvent := fixture["expected_event"].(map[string]any), payload :=
captured["payload"].(map[string]any), usage :=
payload["usage"].(map[string]any), expectedUsage :=
expectedPayload["usage"].(map[string]any), modelUsage :=
payload["model_usage"].([]any)) which can panic on malformed fixtures; replace
these with safe checks (use the "comma ok" form) and call t.Fatalf with clear
messages when a key is missing or the type is wrong, and for modelUsage validate
it is a []any and has at least one element before accessing [0]; ensure you
check captured["payload"], fixture["expected_payload"], and all nested keys
exist and have expected types (expectedEvent, expectedPayload, payload, usage,
expectedUsage, modelUsage) before comparing values so failures report
descriptive errors instead of panics.

In `@node/simpleflow_sdk/index.js`:
- Around line 650-660: Unify the duplicate sampling fields by replacing
sampledForEvent and sampledForEnvelope with a single sampled property: compute
sampled once (currently computed into sampledForEvent) using typeof
telemetry.sampled === "boolean" ? telemetry.sampled : true and return it as
sampled, then update places that read context.sampled (previously using
sampledForEvent/sampledForEnvelope) — specifically change the usages in the code
that reference sampledForEvent and sampledForEnvelope (e.g., the callers around
the former lines where context is built and at the two call sites you noted) to
read context.sampled so the SDK matches the Python single-sampled convention.

In `@python/simpleflow_sdk/response_models.py`:
- Around line 92-97: The file ends without a POSIX newline; add a single
trailing newline at EOF so the ChatSession TypedDict declaration (class
ChatSession) is followed by a newline character. Ensure the file is saved with a
final '\n' after the last line so tools expecting POSIX-compliant files
recognize the newline.

In `@python/tests/test_client.py`:
- Around line 449-455: The test assigns an unused variable `fake_http` from
_new_client(), causing static analysis warnings; rename it to `_fake_http` (or
prefix with an underscore) in the `test_chat_history_list_method` so the call
stays the same but the linter recognizes the variable as intentionally unused;
update the variable name wherever it's referenced in that test (here only in the
assignment) to `_fake_http`.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4f5f5e31-adc9-4e45-81ac-220825772786

📥 Commits

Reviewing files that changed from the base of the PR and between 8024548 and dc0568c.

📒 Files selected for processing (25)
  • .github/workflows/repo-hygiene.yml
  • .gitignore
  • CNAME
  • Makefile
  • README.md
  • code-review/code_smell_fix_plan.md
  • code-review/code_smell_pr_execution_plan.md
  • code-review/code_smell_remediation_technical_plan.md
  • code-review/code_smell_report.md
  • contracts/runtime-registration/action_path_cases.json
  • contracts/telemetry-envelope-v1/workflow_basic.json
  • docs/index.md
  • docs/sdk-go-integration.md
  • docs/sdk-integration-common.md
  • docs/sdk-node-integration.md
  • docs/sdk-python-integration.md
  • go/simpleflow/client.go
  • go/simpleflow/client_test.go
  • go/simpleflow/response_models.go
  • node/simpleflow_sdk/index.js
  • node/simpleflow_sdk/tests/client.test.js
  • python/simpleflow_sdk/__init__.py
  • python/simpleflow_sdk/client.py
  • python/simpleflow_sdk/response_models.py
  • python/tests/test_client.py
💤 Files with no reviewable changes (1)
  • CNAME

Comment on lines +30 to +33
User-scoped APIs:

- `SIMPLEFLOW_USER_BEARER`

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Document the API-key env path alongside bearer for chat use cases.

Line 9 says chat accepts agk_* API key or user bearer, but Line 30–33 only documents SIMPLEFLOW_USER_BEARER. Add an explicit API-key env variable example to avoid ambiguity.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/sdk-integration-common.md` around lines 30 - 33, The docs currently only
list the user bearer env variable `SIMPLEFLOW_USER_BEARER`; add an explicit
API-key env variable entry (e.g., `SIMPLEFLOW_API_KEY` or
`SIMPLEFLOW_AG_API_KEY`) alongside `SIMPLEFLOW_USER_BEARER` to show chat accepts
agk_* API keys or user bearers; update the User-scoped APIs section to include
that API-key env var name and a short example note indicating it accepts agk_*
keys for chat use cases so readers aren’t ambiguous about which env var to set.

Comment on lines +44 to +45
5. Optionally emit span telemetry with `withTelemetry(...).emitSpan(...)`.
6. Use chat history APIs with user bearer token when needed.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Use language-specific method names in the shared sequence.

Line 44 and Line 45 use Node-style names, but Python uses snake_case (write_event_from_workflow_result, with_telemetry(...).emit_span(...)). This can break direct copy/paste for Python integrations.

Suggested wording
-4. Emit canonical telemetry via `writeEventFromWorkflowResult(...)`.
-5. Optionally emit span telemetry with `withTelemetry(...).emitSpan(...)`.
+4. Emit canonical telemetry (Node: `writeEventFromWorkflowResult(...)`, Python: `write_event_from_workflow_result(...)`, Go: `WriteEventFromWorkflowResult(...)`).
+5. Optionally emit span telemetry (Node: `withTelemetry(...).emitSpan(...)`, Python: `with_telemetry(...).emit_span(...)`, Go: `WithTelemetry(...).EmitSpan(...)`).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/sdk-integration-common.md` around lines 44 - 45, Update the shared
sequence wording to use Python snake_case method names instead of Node-style
names so Python users can copy/paste directly: replace Node-style references
like withTelemetry(...).emitSpan(...) and writeEventFromWorkflowResult with the
Python equivalents with_telemetry(...).emit_span(...) and
write_event_from_workflow_result (or include both language variants
side-by-side). Ensure the same change is applied to the chat history guidance to
mention using a user bearer token with the language-appropriate API names (e.g.,
Python snake_case).

Comment thread Makefile
Comment on lines +68 to +73
clean:
rm -rf "docs/node_modules" "docs/.vitepress/dist" "docs/.vitepress/cache"
rm -rf "examples/simpleflow-hr-agent/node_modules" ".opencode/node_modules"
rm -rf "python/dist" "python/build" "python"/*.egg-info
rm -rf "node/simpleflow_sdk/node_modules"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Extend clean to remove Python bytecode artifacts too.

At Line 68–73, clean omits __pycache__/ and *.pyc, but CI blocks those as generated artifacts. This leaves a hygiene gap for local cleanup.

Suggested patch
 clean:
 	rm -rf "docs/node_modules" "docs/.vitepress/dist" "docs/.vitepress/cache"
 	rm -rf "examples/simpleflow-hr-agent/node_modules" ".opencode/node_modules"
 	rm -rf "python/dist" "python/build" "python"/*.egg-info
 	rm -rf "node/simpleflow_sdk/node_modules"
+	find . -type d -name "__pycache__" -prune -exec rm -rf {} +
+	find . -type f -name "*.pyc" -delete
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
clean:
rm -rf "docs/node_modules" "docs/.vitepress/dist" "docs/.vitepress/cache"
rm -rf "examples/simpleflow-hr-agent/node_modules" ".opencode/node_modules"
rm -rf "python/dist" "python/build" "python"/*.egg-info
rm -rf "node/simpleflow_sdk/node_modules"
clean:
rm -rf "docs/node_modules" "docs/.vitepress/dist" "docs/.vitepress/cache"
rm -rf "examples/simpleflow-hr-agent/node_modules" ".opencode/node_modules"
rm -rf "python/dist" "python/build" "python"/*.egg-info
rm -rf "node/simpleflow_sdk/node_modules"
find . -type d -name "__pycache__" -prune -exec rm -rf {} +
find . -type f -name "*.pyc" -delete
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Makefile` around lines 68 - 73, The Makefile's clean target currently removes
various build directories but omits Python bytecode artifacts; update the clean
recipe for the clean target to also remove Python __pycache__ directories and
*.pyc files (e.g., add rm -rf "**/__pycache__" "**/*.pyc" and/or remove
__pycache__ and *.pyc under the python/ and any package dirs referenced by the
existing patterns) so Python bytecode is cleaned alongside python/dist,
python/build, and egg-info; apply the changes within the existing clean target
(referencing the Makefile target name clean) to avoid leaving generated Python
artifacts behind.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dc0568ca99

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if (typeof source.schema_version === "string") result.schema_version = source.schema_version;
if (typeof source.run_id === "string") result.run_id = source.run_id;
if (typeof source.status === "string") result.status = source.status;
if (source.output && typeof source.output === "object" && !Array.isArray(source.output)) result.output = source.output;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve non-object invoke outputs

invoke() now routes through normalizeInvokeResult, but that normalizer only keeps output when it is a non-array object. If the runtime returns a valid scalar/array output (for example a string reply or list payload), the SDK silently drops output from the returned object, which is a behavior regression from the previous raw response passthrough and breaks callers that read response.output.

Useful? React with 👍 / 👎.

Comment on lines +166 to +167
if isinstance(value.get("output"), dict):
result["output"] = value["output"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep scalar invoke output in Python invoke()

The new invoke_typed() normalization only includes output when it is a dict, and invoke() now depends on that path. Any valid invoke response where output is a scalar/array/null is returned without an output key, which is a backward-incompatible behavior change from the prior invoke() passthrough and can make successful runtime results look empty.

Useful? React with 👍 / 👎.

raise TypeError(
"simpleflow sdk payload error: payload must be a dataclass, dict, or None"
)
return {field.name: getattr(payload, field.name) for field in fields(payload)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Recursively serialize dataclass payloads

Switching from asdict to a shallow field copy leaves nested dataclass instances unconverted in payloads. Those nested objects are then forwarded to HTTP JSON encoding, which raises a serialization error for dataclass instances; previously this worked because asdict recursively converted nested dataclasses. This introduces runtime failures for nested dataclass request bodies.

Useful? React with 👍 / 👎.

@CraftsMan-Labs
CraftsMan-Labs merged commit 5f6c2e5 into main Apr 2, 2026
2 checks passed
@CraftsMan-Labs
CraftsMan-Labs deleted the code-smell-remediation branch April 8, 2026 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant