mirror of
https://github.com/geoffsee/open-gsio.git
synced 2025-09-08 22:56:46 +00:00
wip
This commit is contained in:

committed by
Geoff Seemueller

parent
21d6c8604e
commit
554096abb2
34
packages/coordinators/.gitignore
vendored
Normal file
34
packages/coordinators/.gitignore
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
# dependencies (bun install)
|
||||
node_modules
|
||||
|
||||
# output
|
||||
out
|
||||
dist
|
||||
*.tgz
|
||||
|
||||
# code coverage
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# logs
|
||||
logs
|
||||
_.log
|
||||
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# caches
|
||||
.eslintcache
|
||||
.cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# IntelliJ based IDEs
|
||||
.idea
|
||||
|
||||
# Finder (MacOS) folder config
|
||||
.DS_Store
|
3
packages/coordinators/README.md
Normal file
3
packages/coordinators/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# durable_objects
|
||||
|
||||
This package exports implementations of durable objects
|
3
packages/coordinators/index.ts
Normal file
3
packages/coordinators/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import ServerCoordinator from './src/ServerCoordinator';
|
||||
|
||||
export { ServerCoordinator };
|
13
packages/coordinators/package.json
Normal file
13
packages/coordinators/package.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "@open-gsio/coordinators",
|
||||
"module": "index.ts",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1",
|
||||
"@cloudflare/workers-types": "^4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5"
|
||||
}
|
||||
}
|
79
packages/coordinators/src/ServerCoordinator.ts
Normal file
79
packages/coordinators/src/ServerCoordinator.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { ProviderRepository } from '@open-gsio/ai/providers/_ProviderRepository.ts';
|
||||
// @ts-expect-error - don't care
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import { DurableObject } from 'cloudflare:workers';
|
||||
|
||||
export default class ServerCoordinator extends DurableObject {
|
||||
env;
|
||||
state;
|
||||
constructor(state, env) {
|
||||
super(state, env);
|
||||
this.state = state;
|
||||
this.env = env;
|
||||
}
|
||||
|
||||
// Public method to calculate dynamic max tokens
|
||||
async dynamicMaxTokens(model, input, maxOuputTokens) {
|
||||
const modelMeta = ProviderRepository.getModelMeta(model, this.env);
|
||||
|
||||
// The token‑limit information is stored in three different keys:
|
||||
// max_completion_tokens
|
||||
// context_window
|
||||
// context_length
|
||||
|
||||
if ('max_completion_tokens' in modelMeta) {
|
||||
return modelMeta.max_completion_tokens;
|
||||
} else if ('context_window' in modelMeta) {
|
||||
return modelMeta.context_window;
|
||||
} else if ('context_length' in modelMeta) {
|
||||
return modelMeta.context_length;
|
||||
} else {
|
||||
return 2000;
|
||||
}
|
||||
}
|
||||
|
||||
// Public method to retrieve conversation history
|
||||
async getConversationHistory(conversationId) {
|
||||
const history = await this.env.KV_STORAGE.get(`conversations:${conversationId}`);
|
||||
|
||||
return JSON.parse(history) || [];
|
||||
}
|
||||
|
||||
// Public method to save a message to the conversation history
|
||||
async saveConversationHistory(conversationId, message) {
|
||||
const history = await this.getConversationHistory(conversationId);
|
||||
history.push(message);
|
||||
await this.env.KV_STORAGE.put(`conversations:${conversationId}`, JSON.stringify(history));
|
||||
}
|
||||
|
||||
async saveStreamData(streamId, data, ttl = 10) {
|
||||
const expirationTimestamp = Date.now() + ttl * 1000;
|
||||
// await this.state.storage.put(streamId, { data, expirationTimestamp });
|
||||
await this.env.KV_STORAGE.put(
|
||||
`streams:${streamId}`,
|
||||
JSON.stringify({ data, expirationTimestamp }),
|
||||
);
|
||||
}
|
||||
|
||||
// New method to get stream data
|
||||
async getStreamData(streamId) {
|
||||
const streamEntry = await this.env.KV_STORAGE.get(`streams:${streamId}`);
|
||||
if (!streamEntry) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { data, expirationTimestamp } = JSON.parse(streamEntry);
|
||||
if (Date.now() > expirationTimestamp) {
|
||||
// await this.state.storage.delete(streamId); // Clean up expired entry
|
||||
await this.deleteStreamData(`streams:${streamId}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
// New method to delete stream data (cleanup)
|
||||
async deleteStreamData(streamId) {
|
||||
await this.env.KV_STORAGE.delete(`streams:${streamId}`);
|
||||
}
|
||||
}
|
73
packages/coordinators/src/ServerCoordinatorBun.ts
Normal file
73
packages/coordinators/src/ServerCoordinatorBun.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { BunSqliteKVNamespace } from '@open-gsio/server/src/storage/BunSqliteKVNamespace';
|
||||
|
||||
class BunDurableObject {
|
||||
state;
|
||||
env;
|
||||
|
||||
constructor(state: any, env: any) {
|
||||
this.state = state;
|
||||
this.env = env;
|
||||
}
|
||||
|
||||
public static idFromName(name: string) {
|
||||
return name.split('~')[1];
|
||||
}
|
||||
|
||||
public static get(objectId: ObjectId) {
|
||||
// @ts-expect-error - This shouldn't work but it does.
|
||||
// the way that env gets assigned
|
||||
const env = getEnvForObjectId(objectId, this.env);
|
||||
const state = {};
|
||||
return new SiteCoordinator(state, env);
|
||||
}
|
||||
}
|
||||
|
||||
export type ObjectId = string;
|
||||
|
||||
function getEnvForObjectId(objectId: ObjectId, env: any): any {
|
||||
return {
|
||||
...env,
|
||||
KV_STORAGE: new BunSqliteKVNamespace(),
|
||||
};
|
||||
}
|
||||
|
||||
export default class SiteCoordinator extends BunDurableObject {
|
||||
state;
|
||||
env;
|
||||
constructor(state: any, env: any) {
|
||||
super(state, env);
|
||||
this.state = state;
|
||||
this.env = env;
|
||||
}
|
||||
|
||||
async dynamicMaxTokens(input: any, maxOuputTokens: any) {
|
||||
return 2000;
|
||||
}
|
||||
|
||||
async saveStreamData(streamId: string, data: any, ttl = 10) {
|
||||
const expirationTimestamp = Date.now() + ttl * 1000;
|
||||
await this.env.KV_STORAGE.put(
|
||||
`streams:${streamId}`,
|
||||
JSON.stringify({ data, expirationTimestamp }),
|
||||
);
|
||||
}
|
||||
|
||||
async getStreamData(streamId: string) {
|
||||
const streamEntry = await this.env.KV_STORAGE.get(`streams:${streamId}`);
|
||||
if (!streamEntry) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { data, expirationTimestamp } = JSON.parse(streamEntry);
|
||||
if (Date.now() > expirationTimestamp) {
|
||||
await this.deleteStreamData(`streams:${streamId}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
async deleteStreamData(streamId: string) {
|
||||
await this.env.KV_STORAGE.delete(`streams:${streamId}`);
|
||||
}
|
||||
}
|
28
packages/coordinators/tsconfig.json
Normal file
28
packages/coordinators/tsconfig.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
// Environment setup & latest features
|
||||
"lib": ["ESNext"],
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleDetection": "force",
|
||||
"jsx": "react-jsx",
|
||||
"allowJs": true,
|
||||
|
||||
// Bundler mode
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"noEmit": true,
|
||||
|
||||
// Best practices
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
|
||||
// Some stricter flags (disabled by default)
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noPropertyAccessFromIndexSignature": false
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user