Skip to content

feat: add step handler registry for library embedding#395

Merged
eskenazit merged 9 commits intomainfrom
feat/embedding-api
May 6, 2026
Merged

feat: add step handler registry for library embedding#395
eskenazit merged 9 commits intomainfrom
feat/embedding-api

Conversation

@jlouvel
Copy link
Copy Markdown
Contributor

@jlouvel jlouvel commented May 1, 2026

Related Issue

Closes #394


What does this PR do?

Adds a programmatic embedding API that allows Java applications to use the Naftiko Framework as a library. Embedders register StepHandler implementations by step name via StepHandlerRegistry; when the engine encounters a registered step during orchestration, it delegates to the handler instead of the normal call/script/lookup path.

Key components:

  • StepHandler interface — receives StepHandlerContext, returns JsonNode
  • StepHandlerContext — immutable view of execution context (input parameters, prior step outputs, with values)
  • StepHandlerRegistry — maps step names to handlers, executes them with context
  • NaftikoEngine.builder() — fluent API to load YAML from classpath/file and register handlers
  • Integration into OperationStepExecutor — registry check before normal dispatch (single continue path)

The Naftiko Specification (naftiko-schema.json) remains unchanged. This is the prerequisite for Polychro Phase 12 (MCP Server Mode).


Tests

  • StepHandlerRegistryTest — 10 tests covering register/get/has/unregister/execute/null guards
  • StepHandlerContextTest — 8 tests covering accessibility, convenience methods, immutability, null safety
  • NaftikoEngineBuilderTest — 5 tests covering classpath loading, missing resource, handler registration, registry propagation
  • EngineStepHandlerOverrideTest — 5 integration tests verifying handler override, normal path fallback, null output, multi-handler, and step chaining

Checklist

  • CI is green (build, tests, schema validation, security scans)
  • Rebased on latest main
  • Small and focused — one concern per PR
  • Commit messages follow Conventional Commits

Agent Context (optional)

agent_name: GitHub Copilot
llm: Claude Opus 4.6
tool: VS Code Chat
confidence: high
source_event: user request to implement java-class-invocation-step blueprint
review_focus: src/main/java/io/naftiko/engine/step/, src/main/java/io/naftiko/engine/util/OperationStepExecutor.java:184-225

@jlouvel jlouvel self-assigned this May 1, 2026
@jlouvel jlouvel requested a review from eskenazit May 1, 2026 21:51
@jlouvel jlouvel added the enhancement New feature or request label May 1, 2026
@jlouvel
Copy link
Copy Markdown
Contributor Author

jlouvel commented May 1, 2026

@eskenazit This is a dependency for Polychro built-in MCP server

@jlouvel jlouvel force-pushed the feat/embedding-api branch 2 times, most recently from c093ac4 to 8630f8b Compare May 4, 2026 14:38
@eskenazit eskenazit force-pushed the feat/embedding-api branch from 8630f8b to 9015388 Compare May 5, 2026 16:47
Copy link
Copy Markdown
Contributor

@eskenazit eskenazit left a comment

Choose a reason for hiding this comment

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

PR #395 — Step Handler Registry / Embedding API review. One blocking issue (wrong method names in error message) and several smaller findings below.

Comment thread src/main/java/io/naftiko/Capability.java Outdated
Comment thread src/main/java/io/naftiko/engine/util/OperationStepExecutor.java Outdated
Comment thread src/main/java/io/naftiko/engine/util/OperationStepExecutor.java Outdated
Comment thread src/main/java/io/naftiko/engine/step/StepHandler.java
Comment thread src/test/java/io/naftiko/engine/CapabilityBuilderTest.java Outdated
Copy link
Copy Markdown
Contributor

@eskenazit eskenazit left a comment

Choose a reason for hiding this comment

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

Review from Claude Sonnet 4.6

@jlouvel jlouvel force-pushed the feat/embedding-api branch from 9015388 to cc1173b Compare May 6, 2026 03:18
@jlouvel
Copy link
Copy Markdown
Contributor Author

jlouvel commented May 6, 2026

@eskenazit Should be good now

Copy link
Copy Markdown
Contributor

@eskenazit eskenazit left a comment

Choose a reason for hiding this comment

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

Good progress — 4 of 5 threads are resolved. One non-blocking item remains before merge.

Still open: ConcurrentHashMap on local variables in OperationStepExecutor\nThe resolved copy-for-with was fixed, but params, runtimeParameters (top of executeSteps) and stepParams (in mergeStepParameters) are still ConcurrentHashMap. All three are single-threaded stack variables; HashMap is the right type.

New nit: Javadoc @code example in Capability.Builder still shows .capabilityFromClasspath(...) — should be .loadFromClasspath(...) to match the actual API.

Everything else looks clean: the blocking error-message fix, the registry hoisting, the encoding, the test assertions, and the test deduplication are all good.

eskenazit

This comment was marked as duplicate.

@jlouvel
Copy link
Copy Markdown
Contributor Author

jlouvel commented May 6, 2026

@eskenazit Should be good now

jlouvel added 8 commits May 6, 2026 08:27
Provide a programmatic embedding API that allows Java applications to use
the Naftiko Framework as a library. Embedders register StepHandler
implementations by step name; when the engine encounters a registered step
during execution, it delegates to the handler instead of the normal
call/script/lookup path.

Key components:
- StepHandler interface (receives context, returns JsonNode)
- StepHandlerContext (immutable view of execution context)
- StepHandlerRegistry (maps step names to handlers)
- NaftikoEngine.builder() (fluent API to load YAML and register handlers)
- Integration into OperationStepExecutor (registry check before dispatch)

The Naftiko Specification (naftiko-schema.json) remains unchanged.

Closes #394
Add enabled guard to TelemetryBootstrap span factories and EngineMetrics
recording methods. When disabled, span methods return Span.getInvalid()
immediately — no string concatenation, no SpanBuilder allocation, no
Attributes construction.

In embedded library mode (NaftikoEngine), telemetry is off by default.
Embedders can opt in via .telemetry(true) on the builder.
Move the Builder inner class and builder() factory method directly into
Capability, eliminating the NaftikoEngine wrapper. The embedding API is
now Capability.builder()...build() returning a Capability directly.

Rename NaftikoEngineBuilderTest to CapabilityBuilderTest and update
EngineStepHandlerOverrideTest to use Capability.builder().
@jlouvel jlouvel force-pushed the feat/embedding-api branch from 4ab52e5 to 5b0882e Compare May 6, 2026 12:27
Copy link
Copy Markdown
Contributor

@eskenazit eskenazit left a comment

Choose a reason for hiding this comment

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

LGTM

@eskenazit eskenazit merged commit 6191413 into main May 6, 2026
4 checks passed
@eskenazit eskenazit deleted the feat/embedding-api branch May 6, 2026 13:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add step handler registry for library embedding

2 participants