-
Notifications
You must be signed in to change notification settings - Fork 7
refactor: Make makeJsonAgent bundleable with @endo/bundle-source #750
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
d349ac7 to
1cd0e2b
Compare
b817127 to
d269097
Compare
1cd0e2b to
6de5dee
Compare
This refactors kernel-utils and kernel-errors to enable makeJsonAgent to be bundled into vats using @endo/bundle-source. Changes: - kernel-utils: Added subpath exports (counter, merge-disjoint-records, schema) - kernel-errors: Added bundleable subpath with simplified error classes - kernel-errors: Extracted ErrorCode to error-codes.ts (no @metamask/utils dep) - ocap-kernel: Moved isRetryableNetworkError from kernel-errors to utils - kernel-agents: Updated to use subpath imports The bundler was failing due to transitive dependencies on @noble/hashes which has ESM/CJS compatibility issues. By using subpath exports and moving libp2p-specific code to ocap-kernel, we avoid pulling in unbundleable dependencies.
6de5dee to
6c9d512
Compare
| @@ -1,4 +1,4 @@ | |||
| import { SampleGenerationError } from '@metamask/kernel-errors'; | |||
| import { SampleGenerationError } from '@metamask/kernel-errors/bundleable'; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Class identity mismatch breaks retry logic across packages
High Severity
The import of SampleGenerationError changed from @metamask/kernel-errors to @metamask/kernel-errors/bundleable. Since these export different class objects, the instanceof check in withRetries on line 47 will fail for errors thrown by packages that still import from the main export (like kernel-agents-repl). This breaks retry functionality for invalid LLM responses when using makeReplAgent, as errors won't be recognized as retryable and will be thrown immediately instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@claude recommend a fix that works for this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Claude finished @grypez's task in 1m 6s —— View job
Recommended fix for class identity mismatch
I've analyzed the issue and here's my recommendation:
Problem Summary
The PR creates two separate SampleGenerationError classes:
- Main export (
@metamask/kernel-errors): Full-featured version with marshaling logic, extendsBaseError, depends on@metamask/utils - Bundleable export (
@metamask/kernel-errors/bundleable): Lightweight version without marshaling, extendsErrordirectly, no@metamask/utilsdependency
The issue occurs because:
kernel-agents(used in vats) imports from/bundleable(line 1 ofattempt.ts:47)kernel-agents-replimports from the main export (line 1 ofsample-collector.ts:39)- When errors cross package boundaries,
instanceofchecks fail because they're different class objects
Recommended Solution: Use Error Code Checking Instead of instanceof
Since you've already extracted ErrorCode to error-codes.ts (which is already bundleable), the cleanest solution is to replace instanceof checks with error code checks:
In packages/kernel-agents/src/attempt.ts:
import { ErrorCode } from '@metamask/kernel-errors/error-codes';
// Change line 47 from:
(error) => error instanceof SampleGenerationError,
// To:
(error) => error instanceof Error &&
'code' in error &&
error.code === ErrorCode.SampleGenerationError,Why this works:
- ✅ Both versions of
SampleGenerationErrorhave a.codeproperty with the same value - ✅
ErrorCodecan be imported separately without pulling in unbundleable dependencies - ✅ No class identity issues - checking a property value, not class reference
- ✅ Works across package boundaries and different module exports
- ✅ Maintains type safety with proper runtime checks
- ✅ Consistent with the ocap pattern of using structural typing
Alternative (if you need stricter typing):
Create a type guard function in error-codes.ts:
// In packages/kernel-errors/src/error-codes.ts
export const isSampleGenerationError = (error: unknown): error is {
code: typeof ErrorCode.SampleGenerationError;
data: { sample: string };
message: string;
cause?: Error;
} => {
return (
error instanceof Error &&
'code' in error &&
error.code === ErrorCode.SampleGenerationError &&
'data' in error &&
typeof error.data === 'object' &&
error.data !== null &&
'sample' in error.data
);
};Then use it in attempt.ts:
import { isSampleGenerationError } from '@metamask/kernel-errors/error-codes';
// Line 47:
(error) => isSampleGenerationError(error),This approach gives you proper type narrowing and works with both versions of the class.
Refactors kernel-utils and kernel-errors to enable makeJsonAgent to be bundled into vats using @endo/bundle-source.
Changes:
The bundler was failing due to transitive dependencies on @noble/hashes (through @metamask/utils) which has ESM/CJS compatibility issues. By using subpath exports and moving libp2p-specific code to ocap-kernel, we avoid pulling in unbundleable dependencies.
Note
Makes agent and supporting packages bundleable for vats and reduces unbundleable deps.
bundleable/subpath with lightweightSampleGenerationError; extractErrorCode/ErrorSentineltoerror-codes.ts; dropisRetryableNetworkErrorexport; updateBaseErrorand tests accordingly; update exports in package.json.counter,merge-disjoint-records, andschema; movemakeCountertocounter.ts(re-exported frommisc.ts); update package exports.isRetryableNetworkErrorintoutils/with tests; updateConnectionFactoryandnetworkto import it locally.merge-disjoint-records,schema,discoverable); use bundleableSampleGenerationError.Written by Cursor Bugbot for commit 6c9d512. This will update automatically on new commits. Configure here.