npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@bot41/bot41-api

v1.1.118

Published

bot41 api

Downloads

155

Readme

pk sk data1 USER#ID COLLEAGUE#slack#source_id#ID SOURCE#ID USER#ID COLLEAGUE#organic#ID SOURCE#ORGANIC ["COLLEAGUE#ID", "COLLEAGUE#ID"] USER#ID SOURCE#ID USER#ID MESSAGE#ID

PROMPT#ID PROMPT USER#ID PROMPT#userId#name PROMPT#ID PROMPT USER#ID PROMPT#public#name USER#ID MODEL_INSTANCE#ID MODEL_INSTANCE#name

Infrastructure

DynamoDB

Production

sam build -t table-production.yaml && sam deploy \
  --stack-name bot41-production-table \
  --capabilities CAPABILITY_IAM \
  --s3-bucket bot41-eu-central-1 \
  --s3-prefix production-table \
  --region eu-central-1 \
  --profile feedme \
  --parameter-overrides ParameterKey=TableName,ParameterValue=bot41-production-table

Development

sam build -t table-development.yaml && sam deploy \
  --stack-name bot41-development-table \
  --capabilities CAPABILITY_IAM \
  --s3-bucket bot41-eu-central-1 \
  --s3-prefix development-table \
  --region eu-central-1 \
  --profile feedme \
  --parameter-overrides ParameterKey=TableName,ParameterValue=bot41-development-table

Production - messages

sam build -t table-messages.yaml && sam deploy \
  --stack-name bot41-messages-production-table \
  --capabilities CAPABILITY_IAM \
  --s3-bucket bot41-us-east-1 \
  --s3-prefix messages-production-table \
  --region us-east-1 \
  --profile feedme \
  --parameter-overrides ParameterKey=TableName,ParameterValue=bot41-messages-production-table

Development - messages

sam build -t table-messages.yaml && sam deploy \
  --stack-name bot41-messages-development-table \
  --capabilities CAPABILITY_IAM \
  --s3-bucket bot41-eu-central-1 \
  --s3-prefix messages-development-table \
  --region eu-central-1 \
  --profile feedme \
  --parameter-overrides ParameterKey=TableName,ParameterValue=bot41-messages-development-table

Prompts

  • Get prompts by id

    • pk = PROMPT#ID AND sk = PROMPT
    • /prompts/:id
  • Get all private prompts ordered by name (gsi2)

    • sk = PROMPT AND begins_with(data2, PROMPT#userId)
    • /prompts?created_by=USERID&sort=name&q=QUERY
  • Get all public prompts ordered by name

    • sk = PROMPT AND begins_with(data2, PROMPT#public)
    • /prompts?sort=name&q=QUERY
  • Get all private prompts ordered by created date (gsi1)

    • data1 = USER#ID AND begins_with(pk, PROMPT)
    • /prompts?created_by=USERID&sort=created_at
  • Get all public prompts ordered by usage

    • sk = PROMPT (gsi3 and filter on public/private)
    • /prompts?sort=usage

type QueryPrivateName = { created_by: string; sort: "name"; q?: string; }

type QueryPrivateCreatedAt = { created_by: string; sort?: "created_at"; }

type QueryPublicName = { sort?: "name"; q?: string; }

type QueryPublicUsage = { sort: "usage"; }

type Query = QueryPrivateName | QueryPrivateCreatedAt | QueryPublicName | QueryPublicUsage;

const q: Query = { sort: "usage" }

  • People can create new prompts by copying existing prompts
    • When they do that we just create a new entry as private prompt

Models

  • /models behaves exactly like /prompts

Model profiles

  • Get model profiles by id

    • pk = USER#ID AND sk = MODEL_INSTANCE#ID
    • /model-profiles/:id
  • Get all model profiles order by created date

    • pk = USER#ID AND begins_with(sk, MODEL_INSTANCE)
    • /model-profiles?created_by=USERID&sort=created_at
  • Get all model profiles order by name (lsi1)

    • pk = USER#ID AND begins_with(data1, MODEL_INSTANCE)
    • /model-profiles?created_by=USERID&sort=name&q=QUERY
  • Get all model profiles order by model name and filtered by type (lsi2)

    • pk = USER#ID AND begins_with(data2, MODEL_INSTANCE#MODEL_TYPE)
    • /model-profiles?created_by=USERID&model_type=MODEL_TYPE&q=QUERY

Clients

Work just like prompts and models

Datasources

Datasources are just like model instances

  • Datasources are created from clients

  • Get datasource by id

    • pk = USER#ID AND sk = DATASOURCE#ID
    • /datasources/:id
  • Get all datasources ordered by created date

    • pk = USER#ID AND begins_with(sk, DATASOURCE)
    • /datasources?created_by=USERID&sort=created_at
  • Get datasources by name (lsi1)

    • pk = USER#ID AND begins_with(data1, DATASOURCE)
    • /datasources?created_by=USERID&sort=name&q=QUERY
  • Get datasources by client name (lsi2)

    • pk = USER#ID AND begins_with(data2, DATASOURCE#CLIENT_NAME)
    • /datasources?created_by=USERID&client_name=CLIENT_NAME&q=QUERY

Contexts

  • Get context by id

    • pk = USER#ID AND sk = CONTEXT#ID
    • /contexts/:id
  • Get contexts by name (lsi1)

    • pk = USER#ID AND begins_with(data1, CONTEXT#datasourceId)
    • /contexts?datasource_id=DATASOURCE#ID&q=QUERY&created_by=USERID

Users

Users are just like datasources

Messages

Writing Userid in front of every hash key fixes the authentication problem

USER#ID MESSAGE#ID USERID#DATASOURCE#ID CONTEXT#ID USER#ID

pk: DATASOURCE#ID sk: MESSAGE#ID

  • Get message by id

    • pk = USER#ID AND sk = MESSAGE#ID
    • /messages/:id
  • Get messages by datasource id and order by created_at (gsi4)

  • Get messages by context and order by created_at (gsi5)

  • Get messages by user and order by created_at (gsi6)

  • Get all colleagues (order by name, filtered by source type and source id)

    • pk = USER#ID AND begins_with(sk, COLLEAGUE)
      • /colleagues
    • pk = USER#ID AND begins_with(sk, COLLEAGUE#slack)
      • /colleagues?source=slack
    • pk = USER#ID AND begins_with(sk, COLLEAGUE#slack#source_id)
      • /colleagues?source=slack&source_id=SOURCE#ID
  • Get all sources

    • pk = USER#ID AND begins_with(sk, SOURCE)
      • /sources

Different states of data export:

stateDiagram-v2
    [*] --> Idle
    Idle --> Waiting: healthy
    Idle --> Failed: error
    Waiting --> Processing: init
    Waiting --> Failed: error
    Processing --> Processing: update
    Processing --> Success: commit
    Processing --> Failed: error
    Success --> [*]
    Failed --> [*]

Flow of sync:

  • User creates client
    • client includes schema and healthcheck
  • User create datasource from client
    • Datasource includes current schema and data and version of client
  • User starts a sync of a datasource
    • api does healthcheck and write data export entry in dynamodb
      • dataExportId
      • state: healthy (Waiting for client)
    • stream consumer puts a message in webhook sqs when data export entry is created
    • consumer of webhooks sqs tries to call webhook 3 times with 10 seconds delay
      • if success, update data export entry in dynamodb
        • state: processing
      • if fail, update data export entry in dynamodb
        • state: failed
    • stream consumer puts a message on data export failed sqs with a 15 minutes delay when state changed from waiting to processing
      • clients have 15 minutes to complete export
    • consumer of data export failed sqs sets the state to failed if it is still processing
    • client can update data export during the 15 minutes as much as they like with a PATCH { state: processing, data: { ... } }
    • only when client updates data export with a commit the data export is considered complete and messages are written to the datasource
      • state: success

Prompts:

  • Get prompts of user by name
  • Get public prompts by name
  • Get public prompts by usage count
  • Get prompts of user by favorite
  • Every prompt has an optional field with recommended model
  • A prompt needs at least one subject
  • A subject is either a user or a context
  • In the prompt different subjects can be used using "{{subjectA:name}}" or "{{subjectB:name}}"
  • The prompt is parsed and for every subjectX there is going to be an input field for type of subject (user or context) and additional information for the user to fill out
  • Context and user might have different attributes. If you use an attribute that does not exist for the subject the UI should throw an error
  • A prompt might also want to specify the date range of messages to consider (e.g. last 30 days)

Models:

  • Models are handled like clients
  • You can browse models, model instances and create your own model
  • A model requires a webhook url to be called when a report is created
  • The webhook call is a POST with the prompt in the body
  • A model requires a maximum token length that restrict the maximum length of the prompt
  • A model might require additional data (e.g. api key for chat gpt)
  • When a user creates an instance from a model by providing additional data we call it a model-instance

Reports:

  • The POST /reports endpoint should accepts a list of prompts and a list of required subjects combinations. It will then create the product of prompts and subjects (e.g. if there are 3 prompts and 3 subjects it will create 9 reports)
  • A report gets all of the data needed for the prompt. If it exceeds the maximum token length it will split the data into chunks.
  • Before creating a report we should calculate the number of chunks. A prompt of the last 2 years with a lot of data is creating a lot of chunks and therefore a lot of costs.
  • When a report is created we call the webhook of the model with the chunked prompt.
  • Every chunked prompt request has its own state.
  • The state of the report is the state of all of the chunked prompts.
  • Users can look at the result of all of the chunks individually.
  • Users can run additional prompts on top of all of the results (e.g. from all of the results which one is the most convincing). This prompt can be added as a "Consolidation prompt" to the original prompt