Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
1 change: 1 addition & 0 deletions .github/workflows/auto-merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ permissions:

jobs:
pull-request-auto-merge:
if: ${{ !github.event.pull_request.draft }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
Expand Down
12 changes: 6 additions & 6 deletions agents/agent-mastra/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,26 @@
"type": "module",
"dependencies": {
"@ai-sdk/amazon-bedrock": "^3.0.22",
"@ai-sdk/azure": "^2.0.30",
"@ai-sdk/azure": "^2.0.32",
"@mastra/core": "^0.16.3",
"@mastra/libsql": "^0.14.1",
"@mastra/loggers": "^0.10.11",
"@mastra/libsql": "^0.14.2",
"@mastra/loggers": "^0.10.12",
"@mastra/mcp": "^0.12.0",
"@mastra/memory": "^0.15.1",
"@mastra/memory": "^0.15.2",
"langfuse-vercel": "^3.38.5",
"zod": "^3.25.76"
},
"devDependencies": {
"@eslint/compat": "^1.3.2",
"@eslint/js": "^9.35.0",
"@stylistic/eslint-plugin": "^5.3.1",
"@types/node": "^22.18.4",
"@types/node": "^22.18.6",
"eslint": "^9.35.0",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-promise": "^7.2.1",
"mastra": "^0.12.3",
"pnpm": "^10.16.1",
"pnpm": "^10.17.0",
"typescript": "^5.9.2",
"typescript-eslint": "^8.44.0"
}
Expand Down
2 changes: 1 addition & 1 deletion agents/agent-voltagent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"zod": "3.24.2"
},
"devDependencies": {
"@types/node": "^22.18.4",
"@types/node": "^22.18.6",
"tsx": "^4.20.5",
"typescript": "^5.9.2"
}
Expand Down
8 changes: 4 additions & 4 deletions agents/langgraph-deep-agent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
"@eslint/compat": "^1.3.2",
"@eslint/js": "^9.35.0",
"@stylistic/eslint-plugin": "^5.3.1",
"@types/node": "^22.18.4",
"@types/node": "^22.18.6",
"@types/uuid": "^10.0.0",
"@vitest/eslint-plugin": "^1.3.10",
"@vitest/eslint-plugin": "^1.3.12",
"dotenv": "^16.6.1",
"eslint": "^9.35.0",
"eslint-import-resolver-typescript": "^4.4.4",
Expand All @@ -29,13 +29,13 @@
"vitest": "^3.2.4"
},
"dependencies": {
"@aws-sdk/credential-provider-node": "^3.888.0",
"@aws-sdk/credential-provider-node": "^3.891.0",
"@langchain/anthropic": "^0.3.28",
"@langchain/aws": "^0.1.15",
"@langchain/community": "^0.3.56",
"@langchain/langgraph": "^0.4.9",
"@langchain/mcp-adapters": "^0.6.0",
"@langchain/openai": "^0.6.12",
"@langchain/openai": "^0.6.13",
"@smithy/eventstream-codec": "^2.2.0",
"deepagents": "^0.0.2"
}
Expand Down
15 changes: 7 additions & 8 deletions basic/app/eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// @ts-check

import { defineConfig } from 'eslint/config';
import eslint from '@eslint/js';
import stylistic from '@stylistic/eslint-plugin';
import tseslint from 'typescript-eslint';
import { configs, parser } from 'typescript-eslint';
import importPlugin from 'eslint-plugin-import';

import pluginPromise from 'eslint-plugin-promise'
Expand All @@ -17,7 +18,7 @@ const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const gitignorePath = path.resolve(__dirname, '.gitignore');

export default tseslint.config(
export default defineConfig(
includeIgnoreFile(gitignorePath),
{
ignores: [
Expand All @@ -31,24 +32,22 @@ export default tseslint.config(
],
},
eslint.configs.recommended,
...tseslint.configs.strict,
...tseslint.configs.stylistic,
...configs.strict,
...configs.stylistic,
pluginPromise.configs['flat/recommended'],
{
files: ['src/**/*.{ts,tsx}'],
languageOptions: {
parser: tseslint.parser,
parser,
ecmaVersion: 'latest',
sourceType: 'module',
parserOptions: {
projectService: true,
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
},
},
plugins: {
'@stylistic': stylistic,
'@stylistic/ts': stylistic,
'@stylistic/jsx': stylistic,
solid,
},
extends: [importPlugin.flatConfigs.recommended, importPlugin.flatConfigs.typescript],
Expand Down
2 changes: 1 addition & 1 deletion basic/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"@solidjs/router": "^0.15.3",
"@stylistic/eslint-plugin": "^5.3.1",
"@types/crypto-js": "^4.2.2",
"@types/node": "^22.18.4",
"@types/node": "^22.18.6",
"@types/uuid": "^10.0.0",
"crypto-js": "^4.2.0",
"eslint": "^9.35.0",
Expand Down
1 change: 1 addition & 0 deletions basic/cdk/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ cdk.out
!*.config.js
.env*
vite.config.js
eslint.config.js
19 changes: 16 additions & 3 deletions basic/cdk/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
# cloudfront-cdn-template
# Basic Chatbot by LangChain.js on AWS Lambda Functions

## deploy

```sh
yarn install && \
cdk deploy
pnpm install && \
pnpm dlx aws-cdk@latest deploy
```

### Option

#### OpenInference

以下の環境変数に `true` を指定すると、[OpenInference](https://github.com/Arize-ai/openinference/) による OpenTelemetry (OTel) Tracing の Export が有効になります。

- `ENABLED_OPENINFERENCE_TELEMETRY`

また、OpenInferenceのトレースは環境変数`COLLECTOR_ENDPOINT`で指定された OTel Collector にgRPCで伝送されます。
環境変数`COLLECTOR_ENDPOINT`が未指定の場合は`http://localhost:6006/v1/traces`が使用されます。

Comment thread
poad marked this conversation as resolved.
ただし、環境変数`ENABLED_OPENINFERENCE_TELEMETRY`に`true`を指定した場合に限ります。
58 changes: 27 additions & 31 deletions basic/cdk/eslint.config.js → basic/cdk/eslint.config.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
// @ts-check

import { defineConfig } from 'eslint/config';
import eslint from '@eslint/js';
import stylistic from '@stylistic/eslint-plugin';
import tseslint from 'typescript-eslint';
import { configs, parser } from 'typescript-eslint';
import eslintImport from 'eslint-plugin-import';

import vitest from '@vitest/eslint-plugin';

import { includeIgnoreFile } from '@eslint/compat';
Comment thread
poad marked this conversation as resolved.
import path from 'node:path';
import { fileURLToPath } from 'node:url';
Expand All @@ -15,7 +12,7 @@ const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const gitignorePath = path.resolve(__dirname, '.gitignore');

const config = tseslint.config(
const config = defineConfig(
includeIgnoreFile(gitignorePath),
{
ignores: [
Expand All @@ -29,42 +26,41 @@ const config = tseslint.config(
],
},
eslint.configs.recommended,
...tseslint.configs.strict,
...tseslint.configs.stylistic,
...configs.strict,
...configs.stylistic,
{
files: ['{bin,lib,lambda}/**/*.{ts,tsx}', '*.js'],
plugins: {
'@stylistic': stylistic,
},
languageOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
parser,
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig-eslint.json'],
},
},
extends: [
eslintImport.flatConfigs.recommended,
eslintImport.flatConfigs.typescript,
],
settings: {
'import/resolver': {
// You will also need to install and configure the TypeScript resolver
// See also https://github.com/import-js/eslint-import-resolver-typescript#configuration
'typescript': true,
'node': true,
},
},
rules: {
'@stylistic/semi': ['error', 'always'],
'@stylistic/indent': ['error', 2],
'@stylistic/comma-dangle': ['error', 'always-multiline'],
'@stylistic/quotes': ['error', 'single'],
},
},
{
files: ['{bin,lib,lambda}/**/*.{ts,tsx}'],
plugins: {
'@stylistic/ts': stylistic,
},
extends: [eslintImport.flatConfigs.recommended, eslintImport.flatConfigs.typescript],
},
{
files: ['*.js'],
plugins: {
'@stylistic/js': stylistic,
},
},
{
files: ['test/**'], // or any other pattern
plugins: {
vitest
},
rules: {
...vitest.configs.recommended.rules, // you can also use vitest.configs.all.rules to enable all rules
'vitest/max-nested-describe': ['error', { 'max': 3 }] // you can also modify rules' behavior using option like this
},
},
);

export default config;
3 changes: 2 additions & 1 deletion basic/cdk/lambda/handler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import './instrumentation';
Comment thread
poad marked this conversation as resolved.
import { ChatPromptTemplate } from '@langchain/core/prompts';
import { StringOutputParser } from '@langchain/core/output_parsers';
import { CallbackHandler } from 'langfuse-langchain';

import { selectLlm, logger } from '@llm-ts-example/common-backend';

export async function handle(
Expand Down
3 changes: 1 addition & 2 deletions basic/cdk/lambda/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// eslint-disable-next-line import/no-unresolved
import { APIGatewayProxyEvent } from 'aws-lambda';
import { handle } from './handler';
import { v7 as uuidv7 } from 'uuid';

import { logger } from '@llm-ts-example/common-backend';

export const handler = awslambda.streamifyResponse(
Expand Down
42 changes: 42 additions & 0 deletions basic/cdk/lambda/instrumentation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@

import { registerInstrumentations } from '@opentelemetry/instrumentation';
import {
NodeTracerProvider,
SimpleSpanProcessor,
} from '@opentelemetry/sdk-trace-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';
import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api';
import { LangChainInstrumentation } from '@arizeai/openinference-instrumentation-langchain';
import * as lcCallbackManager from '@langchain/core/callbacks/manager';
import { resourceFromAttributes } from '@opentelemetry/resources';

if (process.env.ENABLED_OPENINFERENCE_TELEMETRY === 'true') {
// For troubleshooting, set the log level to DiagLogLevel.DEBUG
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);
Comment thread
poad marked this conversation as resolved.

const provider = new NodeTracerProvider({
spanProcessors: [new SimpleSpanProcessor(
new OTLPTraceExporter({

url: process.env.COLLECTOR_ENDPOINT ?? 'http://localhost:6006/v1/traces',
Comment thread
poad marked this conversation as resolved.
}),
),
],
resource: resourceFromAttributes({
[ATTR_SERVICE_NAME]: 'chat-service',
}),
});

registerInstrumentations({
instrumentations: [],
Comment thread
poad marked this conversation as resolved.
});

// LangChain must be manually instrumented as it doesn't have a traditional module structure
const lcInstrumentation = new LangChainInstrumentation();
lcInstrumentation.manuallyInstrument(lcCallbackManager);

provider.register();

console.log('👀 OpenInference initialized');
}
24 changes: 18 additions & 6 deletions basic/cdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@
"@eslint/js": "^9.35.0",
"@stylistic/eslint-plugin": "^5.3.1",
"@types/aws-lambda": "^8.10.152",
"@types/node": "^22.18.4",
"@types/node": "^22.18.6",
"@types/uuid": "^10.0.0",
"@vitest/eslint-plugin": "^1.3.10",
"aws-cdk": "^2.1029.1",
"@vitest/eslint-plugin": "^1.3.12",
"aws-cdk": "^2.1029.2",
"dotenv": "^16.6.1",
"eslint": "^9.35.0",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-promise": "^7.2.1",
"jiti": "^2.5.1",
"tsx": "^4.20.5",
"typescript": "^5.9.2",
"typescript-eslint": "^8.44.0",
Expand All @@ -34,14 +35,25 @@
"vitest": "^3.2.4"
},
"dependencies": {
"@arizeai/openinference-instrumentation-bedrock": "^0.4.0",
"@arizeai/openinference-instrumentation-langchain": "^3.4.2",
"@aws-lambda-powertools/logger": "^2.26.1",
"@aws-sdk/credential-provider-node": "^3.888.0",
"@aws-sdk/credential-provider-node": "^3.891.0",
"@langchain/anthropic": "^0.3.28",
"@langchain/aws": "^0.1.15",
"@langchain/core": "^0.3.76",
"@langchain/core": "^0.3.77",
"@langchain/langgraph": "^0.4.9",
"@langchain/openai": "^0.6.12",
"@langchain/openai": "^0.6.13",
"@llm-ts-example/common-backend": "workspace:*",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.205.0",
"@opentelemetry/exporter-trace-otlp-proto": "^0.205.0",
"@opentelemetry/instrumentation": "^0.205.0",
"@opentelemetry/resources": "^2.1.0",
"@opentelemetry/sdk-node": "^0.205.0",
"@opentelemetry/sdk-trace-base": "^2.1.0",
"@opentelemetry/sdk-trace-node": "^2.1.0",
Comment thread
poad marked this conversation as resolved.
"@opentelemetry/semantic-conventions": "^1.37.0",
"@smithy/eventstream-codec": "^4.1.1",
"aws-cdk-lib": "^2.215.0",
"constructs": "^10.4.2",
Expand Down
12 changes: 6 additions & 6 deletions basic/cdk/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { it } from 'vitest';
import { test } from 'vitest';
import { handle } from '../lambda/handler';
import { stdout } from 'node:process';
import { PassThrough } from 'node:stream';
Expand All @@ -11,14 +11,14 @@ function sleep(time: number) {
});
}

// eslint-disable-next-line vitest/expect-expect
it('test', { retry: 0 }, async () => {
const model = process.env.USE_MODEL ?? '';
const isDefiendModel = model.length > 0;
test.runIf(isDefiendModel)('test', { retry: 0 }, async () => {
Comment thread
poad marked this conversation as resolved.
Outdated

const sessionId = process.env.FIXED_SESSION_ID && process.env.FIXED_SESSION_ID.length > 0 ? process.env.FIXED_SESSION_ID : new Date().getTime().toString();
const model = process.env.USE_MODEL;
const output = process.env.DISABLE_STDOUT === 'true' ? new PassThrough() : stdout;
const question = process.env.QUESTION && process.env.QUESTION.length > 0 ? process.env.QUESTION : 'あなたは誰?';
const question = process.env.QUESTION && process.env.QUESTION.length > 0 ? process.env.QUESTION : 'あなたは誰?質問と同じ言語で答えてください。';

await handle(`local-${sessionId}`, {question, model}, output);
await sleep(1000);
await sleep(2000);
});
Loading