nomyo4J/AGENTS.md
2026-04-29 17:05:24 +02:00

2.7 KiB

nomyo4J — Agent Instructions

Java 25 port of the NOMYO Python client. Hybrid encryption (RSA-4096 + AES-256-GCM) for secure API communication.

Build & Run

mvn compile          # Java 25, Lombok annotation processor
mvn test             # JUnit Jupiter 5.12.1, @Order enforced
mvn test -Dtest=ClassName   # single test class

Architecture

  • SecureCompletionClient — low-level client: key mgmt, HTTP, encryption, decryption
  • SecureChatCompletion — high-level OpenAI-compatible surface (create(), acreate())
  • Constants — all protocol/crypto constants (version, algorithms, timeouts)
  • SecureMemory — Java 25 FFM SecureBuffer for locked/zeroed memory
  • errors/ — 9 exception classes, all extends Exception (checked), all extends APIError
  • util/Pass2Key (PBKDF2 + AES-GCM), PEMConverter, Splitter
  • EncryptedRequest — wire format model with Gson @SerializedName annotations

Stubbed methods (check before implementing)

  • SecureMemory.lock() — always returns false (FFM doesn't support locking)
  • SecureMemory.unlock() — always returns false
  • SecureMemory.initMemoryLocking() — always returns false

Dependencies

  • Gson (2.13.2) — JSON serialization, in pom.xml
  • Lombok (1.18.44, provided scope) — annotation processor configured in maven-compiler-plugin
  • JUnit Jupiter (5.12.1, test scope)
  • Maven Surefire (3.5.0)

Key files

  • TRANSLATION_REFERENCE.mdprimary documentation. Cross-language spec from Python reference. Read before implementing any method.
  • client_keys/ — contains real RSA keys. Gitignored. Do not commit.
  • Main.java — entry point is static void main()not public static void main(String[]). Cannot run standalone.

Conventions

  • Package: ai.nomyo
  • Lombok: @Getter on fields, @Setter on static flags
  • Tests: @TestMethodOrder(OrderAnnotation.class), @DisplayName on every test
  • Error classes: checked exceptions with statusCode and errorDetails (immutable, via Collections.unmodifiableMap)
  • Key files: PosixFilePermissions.fromString("rw-------") for private, "rw-r--r--" for public
  • RSA: 4096-bit, exponent 65537, OAEP-SHA256 (MGF1 with SHA-256)
  • Protocol constants in Constants.java — marked "never change" (downgrade detection)
  • SecureChatCompletion.acreate() is a sync alias, not async — delegates to create()
  • Streaming is explicitly rejected with IllegalArgumentException
  • SecureCompletionClient.ValueError — inner class, maps to Python ValueError
  • Retry: 429/500/502/503/504 + network errors, exponential backoff 2^(attempt-1)s, default 2 retries
  • All HTTP endpoints use application/octet-stream content type for encrypted payloads