Skip to content

Commit 4172034

Browse files
feat: add complete TypeScript client infrastructure
- Add complete build infrastructure (rollup, jest, eslint) - Add comprehensive test suite with jest - Add CHANGELOG and proper versioning - Add LICENSE file - Add examples directory with usage examples - Add scripts for build automation - Add source code in src/ directory - Add proper TypeScript configuration - Add ESLint configuration for code quality This provides a production-ready TypeScript client library with complete build, test, and development infrastructure.
1 parent cb35d54 commit 4172034

File tree

15 files changed

+7064
-0
lines changed

15 files changed

+7064
-0
lines changed

clients/python/test_import.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
"""Import tests for contextforge_memory_client package."""
2+
3+
4+
def test_package_importable():
5+
"""Test that the package can be imported."""
6+
import contextforge_memory_client # noqa: F401
7+
8+
9+
def test_client_class_importable():
10+
"""Test ContextForgeClient import and validate runtime type."""
11+
from contextforge_memory_client import ContextForgeClient # noqa: F401
12+
13+
assert ContextForgeClient is not None
14+
# Validate that ContextForgeClient is a class
15+
assert isinstance(ContextForgeClient, type)
16+
17+
# Verify it has an __init__ method
18+
assert hasattr(ContextForgeClient, "__init__")
19+
assert callable(ContextForgeClient.__init__)
20+
21+
# Validate connection lifecycle methods
22+
expected_lifecycle_methods = ["close", "__enter__", "__exit__", "__del__"]
23+
for method_name in expected_lifecycle_methods:
24+
assert hasattr(
25+
ContextForgeClient, method_name
26+
), f"Missing lifecycle method: {method_name}"
27+
method = getattr(ContextForgeClient, method_name)
28+
assert callable(method), f"Method {method_name} is not callable"
29+
30+
# Validate core API methods
31+
expected_api_methods = ["health", "search"]
32+
for method_name in expected_api_methods:
33+
assert hasattr(
34+
ContextForgeClient, method_name
35+
), f"Missing API method: {method_name}"
36+
method = getattr(ContextForgeClient, method_name)
37+
assert callable(method), f"Method {method_name} is not callable"
38+
39+
40+
def test_all_exports_available():
41+
"""Test all expected exports are available and validate runtime types."""
42+
from contextforge_memory_client import (
43+
ContextForgeAPIError,
44+
ContextForgeClient,
45+
PermanentAPIError,
46+
RetryConfig,
47+
TimeoutAPIError,
48+
TransientAPIError,
49+
) # noqa: F401
50+
51+
# Verify all classes are importable
52+
assert ContextForgeClient is not None
53+
assert ContextForgeAPIError is not None
54+
assert TransientAPIError is not None
55+
assert PermanentAPIError is not None
56+
assert TimeoutAPIError is not None
57+
assert RetryConfig is not None
58+
59+
# Validate that ContextForgeClient and RetryConfig are classes
60+
assert isinstance(ContextForgeClient, type)
61+
assert isinstance(RetryConfig, type)
62+
63+
# Verify ContextForgeClient has expected methods
64+
assert hasattr(ContextForgeClient, "__init__")
65+
66+
# Validate that error types are subclasses of Exception
67+
assert issubclass(ContextForgeAPIError, Exception)
68+
assert issubclass(TransientAPIError, Exception)
69+
assert issubclass(PermanentAPIError, Exception)
70+
assert issubclass(TimeoutAPIError, Exception)
71+
72+
73+
def test_retry_config_validation():
74+
"""Test RetryConfig class structure and default values."""
75+
from contextforge_memory_client import RetryConfig
76+
77+
# Verify RetryConfig has __init__ method
78+
assert hasattr(RetryConfig, "__init__")
79+
assert callable(RetryConfig.__init__)
80+
81+
# Create a minimal RetryConfig instance with defaults
82+
retry_config = RetryConfig()
83+
84+
# Validate expected attributes are present
85+
expected_attributes = [
86+
"max_attempts",
87+
"base_wait",
88+
"max_wait",
89+
"exponential_multiplier",
90+
"jitter",
91+
]
92+
93+
for attr in expected_attributes:
94+
assert hasattr(retry_config, attr), f"Missing attribute: {attr}"
95+
96+
# Validate default values and types
97+
assert isinstance(retry_config.max_attempts, int)
98+
assert retry_config.max_attempts == 3
99+
100+
assert isinstance(retry_config.base_wait, float)
101+
assert retry_config.base_wait == 1.0
102+
103+
assert isinstance(retry_config.max_wait, float)
104+
assert retry_config.max_wait == 60.0
105+
106+
assert isinstance(retry_config.exponential_multiplier, float)
107+
assert retry_config.exponential_multiplier == 2.0
108+
109+
assert isinstance(retry_config.jitter, bool)
110+
assert retry_config.jitter is True
111+
112+
# Test custom initialization
113+
custom_config = RetryConfig(
114+
max_attempts=5,
115+
base_wait=0.5,
116+
max_wait=30.0,
117+
exponential_multiplier=1.5,
118+
jitter=False,
119+
)
120+
121+
assert custom_config.max_attempts == 5
122+
assert custom_config.base_wait == 0.5
123+
assert custom_config.max_wait == 30.0
124+
assert custom_config.exponential_multiplier == 1.5
125+
assert custom_config.jitter is False

clients/typescript/.eslintignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.eslintrc.js
2+
*.config.js
3+
node_modules/
4+
dist/

clients/typescript/.eslintrc.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
module.exports = {
2+
parser: '@typescript-eslint/parser',
3+
extends: [
4+
'eslint:recommended',
5+
'plugin:@typescript-eslint/recommended',
6+
],
7+
plugins: ['@typescript-eslint'],
8+
parserOptions: {
9+
ecmaVersion: 2020,
10+
sourceType: 'module',
11+
lib: ['ES2020', 'DOM'],
12+
},
13+
rules: {
14+
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
15+
'@typescript-eslint/explicit-function-return-type': ['error', {
16+
allowExpressions: true,
17+
allowTypedFunctionExpressions: true
18+
}],
19+
'@typescript-eslint/explicit-module-boundary-types': 'off',
20+
'@typescript-eslint/no-explicit-any': 'error',
21+
'@typescript-eslint/no-inferrable-types': 'off',
22+
'@typescript-eslint/strict-boolean-expressions': 'warn',
23+
'prefer-const': 'error',
24+
'no-var': 'error',
25+
'no-unused-vars': 'off', // Turn off base rule as it can conflict with @typescript-eslint/no-unused-vars
26+
},
27+
env: {
28+
node: true,
29+
es6: true,
30+
jest: true,
31+
},
32+
};

clients/typescript/.gitignore

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Dependencies
2+
node_modules/
3+
npm-debug.log*
4+
yarn-debug.log*
5+
yarn-error.log*
6+
7+
# Build outputs
8+
dist/
9+
build/
10+
*.tsbuildinfo
11+
12+
# Coverage reports
13+
coverage/
14+
*.lcov
15+
16+
# IDE files
17+
.vscode/
18+
.idea/
19+
*.swp
20+
*.swo
21+
22+
# OS files
23+
.DS_Store
24+
Thumbs.db
25+
26+
# Environment files
27+
.env
28+
.env.local
29+
.env.development.local
30+
.env.test.local
31+
.env.production.local
32+
33+
# Logs
34+
logs/
35+
*.log
36+
37+
# Runtime data
38+
pids/
39+
*.pid
40+
*.seed
41+
*.pid.lock
42+
43+
# Optional npm cache directory
44+
.npm
45+
46+
# Optional eslint cache
47+
.eslintcache
48+
49+
# Microbundle cache
50+
.rpt2_cache/
51+
.rts2_cache_cjs/
52+
.rts2_cache_es/
53+
.rts2_cache_umd/
54+
55+
# Optional REPL history
56+
.node_repl_history
57+
58+
# Output of 'npm pack'
59+
*.tgz
60+
61+
# Yarn Integrity file
62+
.yarn-integrity
63+
64+
# parcel-bundler cache (https://parceljs.org/)
65+
.cache
66+
.parcel-cache
67+
68+
# next.js build output
69+
.next
70+
71+
# nuxt.js build output
72+
.nuxt
73+
74+
# vuepress build output
75+
.vuepress/dist
76+
77+
# Serverless directories
78+
.serverless
79+
80+
# FuseBox cache
81+
.fusebox/
82+
83+
# DynamoDB Local files
84+
.dynamodb/

clients/typescript/CHANGELOG.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Changelog
2+
3+
All notable changes to the ContextForge Memory Client will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased]
9+
10+
### Added
11+
- NPM package distribution with `@contextforge/memory-client`
12+
- TypeScript definitions included in package
13+
- CommonJS and ES module builds
14+
- CI/CD pipeline for automated testing and publishing
15+
- Comprehensive test suite with Jest
16+
- Build configuration with TypeScript and Rollup
17+
- Initial release of ContextForge Memory Client
18+
- Support for both v0 and v1 API endpoints
19+
- Memory item storage and retrieval
20+
- Vector search capabilities
21+
- Embedding generation
22+
- Session checkpoint and restore functionality
23+
- Comprehensive error handling with custom error types
24+
- Retry logic with exponential backoff
25+
- Request timeout handling
26+
- TypeScript support with full type definitions
27+
28+
### Features
29+
- **v0 API Support**: Health checks, store, search, and embed endpoints
30+
- **v1 API Support**: Enhanced store, search, embed, checkpoint, and restore endpoints
31+
- **Authentication**: Optional API key support for v1 endpoints
32+
- **Error Handling**: Custom error types for better debugging
33+
- **Retry Logic**: Configurable retry behavior for transient failures
34+
- **Timeout Support**: Configurable request timeouts
35+
- **Type Safety**: Full TypeScript definitions for all APIs
36+
37+
### API Endpoints
38+
- `health()` - Check service health
39+
- `store(items)` - Store memory items (v0)
40+
- `search(namespace, project_id, query, top_k)` - Search memory items (v0)
41+
- `embed(texts)` - Generate embeddings (v0)
42+
- `v1Store(items, vectors?)` - Store memory items with optional vectors (v1)
43+
- `v1Search(namespace, project_id, query, top_k)` - Search memory items (v1)
44+
- `v1Embed(texts)` - Generate embeddings (v1)
45+
- `v1Checkpoint(session_id, phase, summary?, metadata?)` - Create session checkpoint (v1)
46+
- `v1Restore(session_id, task, top_k)` - Restore session context (v1)
47+
48+
### Changed
49+
- Enhanced README with dual installation options (NPM + single-file)
50+
- Improved documentation with migration guides
51+
- Added semantic versioning guidance
52+
53+
## [0.1.0] - TBD
54+
55+
### Added
56+
- Initial release of ContextForge Memory Client
57+
- Support for both v0 and v1 API endpoints
58+
- Memory item storage and retrieval
59+
- Vector search capabilities
60+
- Embedding generation
61+
- Session checkpoint and restore functionality
62+
- Comprehensive error handling with custom error types
63+
- Retry logic with exponential backoff
64+
- Request timeout handling
65+
- TypeScript support with full type definitions
66+
67+
### Features
68+
- **v0 API Support**: Health checks, store, search, and embed endpoints
69+
- **v1 API Support**: Enhanced store, search, embed, checkpoint, and restore endpoints
70+
- **Authentication**: Optional API key support for v1 endpoints
71+
- **Error Handling**: Custom error types for better debugging
72+
- **Retry Logic**: Configurable retry behavior for transient failures
73+
- **Timeout Support**: Configurable request timeouts
74+
- **Type Safety**: Full TypeScript definitions for all APIs
75+
76+
### API Endpoints
77+
- `health()` - Check service health
78+
- `store(items)` - Store memory items (v0)
79+
- `search(namespace, project_id, query, top_k)` - Search memory items (v0)
80+
- `embed(texts)` - Generate embeddings (v0)
81+
- `v1Store(items, vectors?)` - Store memory items with optional vectors (v1)
82+
- `v1Search(namespace, project_id, query, top_k)` - Search memory items (v1)
83+
- `v1Embed(texts)` - Generate embeddings (v1)
84+
- `v1Checkpoint(session_id, phase, summary?, metadata?)` - Create session checkpoint (v1)
85+
- `v1Restore(session_id, task, top_k)` - Restore session context (v1)

clients/typescript/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 bofh
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)