Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4dd3d1b
Release 0.8.21
fern-api[bot] May 21, 2025
94b6276
Merge custom code from old p_sync/pull branch with latest autogenerat…
AlePouroullis May 20, 2025
948de3a
refactor(sync): rename SyncClient to FileSyncer and align with Python…
AlePouroullis May 20, 2025
b00c3b4
refactor(sync): align FileSyncer with Python SDK and improve TypeScri…
AlePouroullis May 20, 2025
2cec6e1
Match CLI functionality with Python SDK; Simplify logging
AlePouroullis May 20, 2025
a3940fa
refactor: implement unified client overloading system
AlePouroullis May 20, 2025
175e42b
refactor: extract path normalization in FileSyncer to separate util
AlePouroullis May 20, 2025
3216839
Add tests for pathUtils and fix regression found from new tests
AlePouroullis May 20, 2025
322759b
tests: Write unit tests for FileSyncer; fix total page calculation bug
AlePouroullis May 20, 2025
1230875
test: Write integration tests for FileSyncer:
AlePouroullis May 20, 2025
419cacf
Fix broken relative paths in decorators.test.ts
AlePouroullis May 20, 2025
8375441
Improve test cleanup; write tests for local file operations
AlePouroullis May 20, 2025
7b4b98f
test: Write tests for CLI
AlePouroullis May 20, 2025
af8cf59
test: Increase timeout of cleanup in slow integration tests
AlePouroullis May 20, 2025
c08d600
Updated deps needed to successfully run the tests
AlePouroullis May 20, 2025
30acd52
test: Increase timeout for pull_basic test as the pagination can be slow
AlePouroullis May 20, 2025
38e6dc8
docs: Add Syncing Files section to README
AlePouroullis May 21, 2025
142a4c7
test: Add decorator and local file overload interaction tests; increa…
AlePouroullis May 21, 2025
1de00ca
chore: Bump version to 0.8.21-beta2
AlePouroullis May 21, 2025
63cd603
test: use npx ts-node for CLI integration tests
AlePouroullis May 21, 2025
d2ac5a2
docs: add comprehensive documentation for CLI test helper
AlePouroullis May 21, 2025
29d9ad9
fix: shorten CLI main help text while preserving detailed subcommand …
AlePouroullis May 21, 2025
82d4488
fix: Remove duplicate dependencies
AlePouroullis May 21, 2025
4e5174f
test: remove skipped API key validation test from CLI integration tests
AlePouroullis May 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .fernignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ src/humanloop.client.ts
src/overload.ts
src/error.ts
src/context.ts
src/cli.ts
src/cache
src/sync

# Tests

# Modified due to issues with OTEL
tests/unit/fetcher/stream-wrappers/webpack.test.ts
tests/custom/

# CI Action

Expand Down
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,47 @@ try {
}
```

## Store Humanloop Files in Code

Humanloop allows you to maintain Prompts and Agents in your local filesystem and version control, while still leveraging Humanloop's prompt management capabilities.

### Syncing Files with the CLI

```bash
# Basic usage
npx humanloop pull # Pull all files to 'humanloop/' directory
npx humanloop pull --path="examples/chat" # Pull specific directory
npx humanloop pull --environment="production" # Pull from specific environment
npx humanloop pull --local-files-directory="ai" # Specify local destination (default: "humanloop")

# View available options
npx humanloop pull --help
```

### Using Local Files in the SDK

To use local Files in your code:

```typescript
// Enable local file support
const client = new HumanloopClient({
apiKey: "YOUR_API_KEY",
useLocalFiles: true
});

// Call a local Prompt file
const response = await client.prompts.call({
path: "examples/chat/basic", // Looks for humanloop/examples/chat/basic.prompt
inputs: { query: "Hello world" }
});

// The same path-based approach works with prompts.log(), agents.call(), and agents.log()
```

For detailed instructions, see our [Guide on Storing Files in Code](https://humanloop.com/docs/v5/guides/prompts/store-prompts-in-code).

For information about file formats, see our [File Format Reference](https://humanloop.com/docs/v5/reference/serialized-files).

## Pagination

List endpoints are paginated. The SDK provides an iterator so that you can simply loop over the items:
Expand Down
7 changes: 6 additions & 1 deletion jest.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ export default {
preset: "ts-jest",
testEnvironment: "node",
moduleNameMapper: {
"(.+)\.js$": "$1",
// Only map .js files in our src directory, not node_modules
"^src/(.+)\\.js$": "<rootDir>/src/$1",
},
// Add transformIgnorePatterns to handle ESM modules in node_modules
transformIgnorePatterns: [
"node_modules/(?!(@traceloop|js-tiktoken|base64-js)/)",
],
};
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
"@traceloop/instrumentation-cohere": ">=0.11.1",
"@traceloop/instrumentation-openai": ">=0.11.3",
"@traceloop/ai-semantic-conventions": ">=0.11.6",
"dotenv": "^16.5.0",
"commander": "^14.0.0",
"cli-progress": "^3.12.0",
"lodash": "^4.17.21"
},
Expand All @@ -46,7 +48,7 @@
"openai": "^4.74.0",
"@anthropic-ai/sdk": "^0.32.1",
"cohere-ai": "^7.15.0",
"dotenv": "^16.4.6",
"ts-node": "^10.9.2",
"jsonschema": "^1.4.1",
"@types/cli-progress": "^3.11.6",
"@types/lodash": "4.14.74",
Expand All @@ -56,5 +58,8 @@
"fs": false,
"os": false,
"path": false
},
"bin": {
"humanloop": "./cli.js"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export interface AgentLogRequest {
* The Agent configuration to use. Two formats are supported:
* - An object representing the details of the Agent configuration
* - A string representing the raw contents of a .agent file
*
* A new Agent version will be created if the provided details do not match any existing version.
*/
agent?: Humanloop.AgentLogRequestAgent;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export interface AgentsCallRequest {
* The Agent configuration to use. Two formats are supported:
* - An object representing the details of the Agent configuration
* - A string representing the raw contents of a .agent file
*
* A new Agent version will be created if the provided details do not match any existing version.
*/
agent?: Humanloop.AgentsCallRequestAgent;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export interface AgentsCallStreamRequest {
* The Agent configuration to use. Two formats are supported:
* - An object representing the details of the Agent configuration
* - A string representing the raw contents of a .agent file
*
* A new Agent version will be created if the provided details do not match any existing version.
*/
agent?: Humanloop.AgentsCallStreamRequestAgent;
Expand Down
1 change: 1 addition & 0 deletions src/api/resources/agents/types/AgentLogRequestAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as Humanloop from "../../../index";
* The Agent configuration to use. Two formats are supported:
* - An object representing the details of the Agent configuration
* - A string representing the raw contents of a .agent file
*
* A new Agent version will be created if the provided details do not match any existing version.
*/
export type AgentLogRequestAgent = Humanloop.AgentKernelRequest | string;
1 change: 1 addition & 0 deletions src/api/resources/agents/types/AgentsCallRequestAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as Humanloop from "../../../index";
* The Agent configuration to use. Two formats are supported:
* - An object representing the details of the Agent configuration
* - A string representing the raw contents of a .agent file
*
* A new Agent version will be created if the provided details do not match any existing version.
*/
export type AgentsCallRequestAgent = Humanloop.AgentKernelRequest | string;
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as Humanloop from "../../../index";
* The Agent configuration to use. Two formats are supported:
* - An object representing the details of the Agent configuration
* - A string representing the raw contents of a .agent file
*
* A new Agent version will be created if the provided details do not match any existing version.
*/
export type AgentsCallStreamRequestAgent = Humanloop.AgentKernelRequest | string;
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export interface PromptLogRequest {
* The Prompt configuration to use. Two formats are supported:
* - An object representing the details of the Prompt configuration
* - A string representing the raw contents of a .prompt file
*
* A new Prompt version will be created if the provided details do not match any existing version.
*/
prompt?: Humanloop.PromptLogRequestPrompt;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export interface PromptsCallRequest {
* The Prompt configuration to use. Two formats are supported:
* - An object representing the details of the Prompt configuration
* - A string representing the raw contents of a .prompt file
*
* A new Prompt version will be created if the provided details do not match any existing version.
*/
prompt?: Humanloop.PromptsCallRequestPrompt;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export interface PromptsCallStreamRequest {
* The Prompt configuration to use. Two formats are supported:
* - An object representing the details of the Prompt configuration
* - A string representing the raw contents of a .prompt file
*
* A new Prompt version will be created if the provided details do not match any existing version.
*/
prompt?: Humanloop.PromptsCallStreamRequestPrompt;
Expand Down
1 change: 1 addition & 0 deletions src/api/resources/prompts/types/PromptLogRequestPrompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as Humanloop from "../../../index";
* The Prompt configuration to use. Two formats are supported:
* - An object representing the details of the Prompt configuration
* - A string representing the raw contents of a .prompt file
*
* A new Prompt version will be created if the provided details do not match any existing version.
*/
export type PromptLogRequestPrompt = Humanloop.PromptKernelRequest | string;
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as Humanloop from "../../../index";
* The Prompt configuration to use. Two formats are supported:
* - An object representing the details of the Prompt configuration
* - A string representing the raw contents of a .prompt file
*
* A new Prompt version will be created if the provided details do not match any existing version.
*/
export type PromptsCallRequestPrompt = Humanloop.PromptKernelRequest | string;
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as Humanloop from "../../../index";
* The Prompt configuration to use. Two formats are supported:
* - An object representing the details of the Prompt configuration
* - A string representing the raw contents of a .prompt file
*
* A new Prompt version will be created if the provided details do not match any existing version.
*/
export type PromptsCallStreamRequestPrompt = Humanloop.PromptKernelRequest | string;
48 changes: 48 additions & 0 deletions src/cache/LRUCache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* LRU Cache implementation
*/
export default class LRUCache<K, V> {
private cache: Map<K, V>;
private readonly maxSize: number;

constructor(maxSize: number) {
this.cache = new Map<K, V>();
this.maxSize = maxSize;
}

get(key: K): V | undefined {
if (!this.cache.has(key)) {
return undefined;
}

// Get the value
const value = this.cache.get(key);

// Remove key and re-insert to mark as most recently used
this.cache.delete(key);
this.cache.set(key, value!);

return value;
}

set(key: K, value: V): void {
// If key already exists, refresh its position
if (this.cache.has(key)) {
this.cache.delete(key);
}
// If cache is full, remove the least recently used item (first item in the map)
else if (this.cache.size >= this.maxSize) {
const lruKey = this.cache.keys().next().value;
if (lruKey) {
this.cache.delete(lruKey);
}
}

// Add new key-value pair
this.cache.set(key, value);
}

clear(): void {
this.cache.clear();
}
}
1 change: 1 addition & 0 deletions src/cache/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as LRUCache } from './LRUCache';
Loading