initial commit

This commit is contained in:
Wanja Krah
2025-11-27 18:11:07 +01:00
commit 914f8537d6
16 changed files with 687 additions and 0 deletions

39
storymaker/.gitignore vendored Normal file
View File

@@ -0,0 +1,39 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
.kotlin
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

8
storymaker/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

7
storymaker/.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

14
storymaker/.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="temurin-25" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PalantirJavaFormatSettings">
<option name="enabled" value="false" />
</component>
</project>

View File

@@ -0,0 +1,3 @@
-s.mvn\settings-local.xml
-Dmaven.repo.local=D:\workspace\private\.m2repo

View File

@@ -0,0 +1,265 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!--
| This is the configuration file for Maven. It can be specified at two levels:
|
| 1. User Level. This settings.xml file provides configuration for a single user,
| and is normally provided in ${user.home}/.m2/settings.xml.
|
| NOTE: This location can be overridden with the CLI option:
|
| -s /path/to/user/settings.xml
|
| 2. Global Level. This settings.xml file provides configuration for all Maven
| users on a machine (assuming they're all using the same Maven
| installation). It's normally provided in
| ${maven.conf}/settings.xml.
|
| NOTE: This location can be overridden with the CLI option:
|
| -gs /path/to/global/settings.xml
|
| The sections in this sample file are intended to give you a running start at
| getting the most out of your Maven installation. Where appropriate, the default
| values (values used when the setting is not specified) are provided.
|
|-->
<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 https://maven.apache.org/xsd/settings-1.2.0.xsd">
<!-- localRepository
| The path to the local repository maven will use to store artifacts.
|
| Default: ${user.home}/.m2/repository
<localRepository>/path/to/local/repo</localRepository>
-->
<!-- interactiveMode
| This will determine whether maven prompts you when it needs input. If set to false,
| maven will use a sensible default value, perhaps based on some other setting, for
| the parameter in question.
|
| Default: true
<interactiveMode>true</interactiveMode>
-->
<!-- offline
| Determines whether maven should attempt to connect to the network when executing a build.
| This will have an effect on artifact downloads, artifact deployment, and others.
|
| Default: false
<offline>false</offline>
-->
<!-- pluginGroups
| This is a list of additional group identifiers that will be searched when resolving plugins by their prefix, i.e.
| when invoking a command line like "mvn prefix:goal". Maven will automatically add the group identifiers
| "org.apache.maven.plugins" and "org.codehaus.mojo" if these are not already contained in the list.
|-->
<pluginGroups>
<!-- pluginGroup
| Specifies a further group identifier to use for plugin lookup.
<pluginGroup>com.your.plugins</pluginGroup>
-->
</pluginGroups>
<!-- TODO Since when can proxies be selected as depicted? -->
<!-- proxies
| This is a list of proxies which can be used on this machine to connect to the network.
| Unless otherwise specified (by system property or command-line switch), the first proxy
| specification in this list marked as active will be used.
|-->
<proxies>
<!-- proxy
| Specification for one proxy, to be used in connecting to the network.
|
<proxy>
<id>optional</id>
<active>true</active>
<protocol>http</protocol>
<username>proxyuser</username>
<password>proxypass</password>
<host>proxy.host.net</host>
<port>80</port>
<nonProxyHosts>local.net|some.host.com</nonProxyHosts>
</proxy>
-->
</proxies>
<!-- servers
| This is a list of authentication profiles, keyed by the server-id used within the system.
| Authentication profiles can be used whenever maven must make a connection to a remote server.
|-->
<servers>
<!-- server
| Specifies the authentication information to use when connecting to a particular server, identified by
| a unique name within the system (referred to by the 'id' attribute below).
|
| NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are
| used together.
|
<server>
<id>deploymentRepo</id>
<username>repouser</username>
<password>repopwd</password>
</server>
-->
<!-- Another sample, using keys to authenticate.
<server>
<id>siteServer</id>
<privateKey>/path/to/private/key</privateKey>
<passphrase>optional; leave empty if not used.</passphrase>
</server>
-->
</servers>
<!-- mirrors
| This is a list of mirrors to be used in downloading artifacts from remote repositories.
|
| It works like this: a POM may declare a repository to use in resolving certain artifacts.
| However, this repository may have problems with heavy traffic at times, so people have mirrored
| it to several places.
|
| That repository definition will have a unique id, so we can create a mirror reference for that
| repository, to be used as an alternate download site. The mirror site will be the preferred
| server for that repository.
|-->
<mirrors>
<!-- mirror
| Specifies a repository mirror site to use instead of a given repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
|
<mirror>
<id>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
-->
<mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
<blocked>true</blocked>
</mirror>
</mirrors>
<!-- profiles
| This is a list of profiles which can be activated in a variety of ways, and which can modify
| the build process. Profiles provided in the settings.xml are intended to provide local machine-
| specific paths and repository locations which allow the build to work in the local environment.
|
| For example, if you have an integration testing plugin - like cactus - that needs to know where
| your Tomcat instance is installed, you can provide a variable here such that the variable is
| dereferenced during the build process to configure the cactus plugin.
|
| As noted above, profiles can be activated in a variety of ways. One way - the activeProfiles
| section of this document (settings.xml) - will be discussed later. Another way essentially
| relies on the detection of a property, either matching a particular value for the property,
| or merely testing its existence. Profiles can also be activated by JDK version prefix, where a
| value of '1.4' might activate a profile when the build is executed on a JDK version of '1.4.2_07'.
| Finally, the list of active profiles can be specified directly from the command line.
|
| NOTE: For profiles defined in the settings.xml, you are restricted to specifying only artifact
| repositories, plugin repositories, and free-form properties to be used as configuration
| variables for plugins in the POM.
|
|-->
<profiles>
<!-- profile
| Specifies a set of introductions to the build process, to be activated using one or more of the
| mechanisms described above. For inheritance purposes, and to activate profiles via <activatedProfiles/>
| or the command line, profiles have to have an ID that is unique.
|
| An encouraged best practice for profile identification is to use a consistent naming convention
| for profiles, such as 'env-dev', 'env-test', 'env-production', 'user-jdcasey', 'user-brett', etc.
| This will make it more intuitive to understand what the set of introduced profiles is attempting
| to accomplish, particularly when you only have a list of profile id's for debug.
|
| This profile example uses the JDK version to trigger activation, and provides a JDK-specific repo.
<profile>
<id>jdk-1.4</id>
<activation>
<jdk>1.4</jdk>
</activation>
<repositories>
<repository>
<id>jdk14</id>
<name>Repository for JDK 1.4 builds</name>
<url>http://www.myhost.com/maven/jdk14</url>
<layout>default</layout>
<snapshotPolicy>always</snapshotPolicy>
</repository>
</repositories>
</profile>
-->
<!--
| Here is another profile, activated by the property 'target-env' with a value of 'dev', which
| provides a specific path to the Tomcat instance. To use this, your plugin configuration might
| hypothetically look like:
|
| ...
| <plugin>
| <groupId>org.myco.myplugins</groupId>
| <artifactId>myplugin</artifactId>
|
| <configuration>
| <tomcatLocation>${tomcatPath}</tomcatLocation>
| </configuration>
| </plugin>
| ...
|
| NOTE: If you just wanted to inject this configuration whenever someone set 'target-env' to
| anything, you could just leave off the <value/> inside the activation-property.
|
<profile>
<id>env-dev</id>
<activation>
<property>
<name>target-env</name>
<value>dev</value>
</property>
</activation>
<properties>
<tomcatPath>/path/to/tomcat/instance</tomcatPath>
</properties>
</profile>
-->
</profiles>
<!-- activeProfiles
| List of profiles that are active for all builds.
|
<activeProfiles>
<activeProfile>alwaysActiveProfile</activeProfile>
<activeProfile>anotherAlwaysActiveProfile</activeProfile>
</activeProfiles>
-->
</settings>

81
storymaker/pom.xml Normal file
View File

@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>nl.agilecc</groupId>
<artifactId>storymaker</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>25</maven.compiler.source>
<maven.compiler.target>25</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<langchain4j.version>1.7.1</langchain4j.version>
<maven-toolchains-plugin.version>3.2.0</maven-toolchains-plugin.version>
<maven-compiler-plugin.version>3.14.1</maven-compiler-plugin.version>
<maven-resources-plugin.version>3.3.1</maven-resources-plugin.version>
<maven-surefire-plugin.version>3.5.4</maven-surefire-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-toolchains-plugin</artifactId>
<version>${maven-toolchains-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>toolchain</goal>
</goals>
</execution>
</executions>
<configuration>
<toolchains>
<jdk>
<version>25</version>
<vendor>openjdk</vendor>
</jdk>
</toolchains>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,14 @@
package nl.agilecc;
import nl.agilecc.service.OpenAiService;
//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
public class Main {
static void main() {
//TIP Press <shortcut actionId="ShowIntentionActions"/> with your caret at the highlighted text
// to see how IntelliJ IDEA suggests fixing it.
// new OpenAiService().hello();
new OpenAiService().createStory();
}
}

View File

@@ -0,0 +1,12 @@
package nl.agilecc.model;
public record AiVraag(String rol, String context, String opdracht, String kaders) {
@Override
public String toString() {
return """
Je rol is: %s
De context is: %s
Je opdracht is: %s
Je kaders zijn: %s""".formatted(rol, context, opdracht, kaders);
}
}

View File

@@ -0,0 +1,4 @@
package nl.agilecc.model;
public record Persona() {
}

View File

@@ -0,0 +1,36 @@
package nl.agilecc.model;
import dev.langchain4j.model.chat.request.json.JsonArraySchema;
import dev.langchain4j.model.chat.request.json.JsonObjectSchema;
import dev.langchain4j.model.chat.request.json.JsonSchema;
import dev.langchain4j.model.chat.request.json.JsonStringSchema;
import java.util.List;
public record Plot(String locatie, List<String> personages, String relaties, String acties, String fases, String ontwikkeling, String aanpak) {
public static String omschrijvingPlot() {
return """
Als locatie willen we weten waar, of in welke setting het verhaal af gaat spelen.
We willen een lijst van personages, per personage een korte omschrijving. Later worden deze personages nog verder uitgewerkt.
We willen alvast een idee van de relaties die de personages hebben tot elkaar.
We willen alvast weten welke acties de personages zich grofweg mee gaan bezig houden.
We willen weten welke ontwikkeling we verwachten dat de personages, of in ieder geval de belangrijkste personages, door gaan maken.
Tot slot willen we weten wat de aanpak waarmee het centrale probleem wordt aangepakt.""";
}
public static JsonSchema getJsonSchema() {
return JsonSchema.builder()
.name("Plot")
.rootElement(JsonObjectSchema.builder()
.addStringProperty("locatie")
.addProperty("personages", JsonArraySchema.builder().items(JsonStringSchema.builder().description("persona").build()).build())
.addStringProperty("relaties")
.addStringProperty("acties")
.addStringProperty("fases")
.addStringProperty("ontwikkeling")
.addStringProperty("aanpak")
.build())
.build();
}
}

View File

@@ -0,0 +1,4 @@
package nl.agilecc.model;
public record Section() {
}

View File

@@ -0,0 +1,4 @@
package nl.agilecc.model;
public record Story() {
}

View File

@@ -0,0 +1,8 @@
package nl.agilecc.model;
public record UserInput(String doelgroep, String genre, String setting, String personages, String conflict) {
@Override
public String toString() {
return "Voor de doelgroep %s, met als genre %s, met ls setting %s, met als personages %s, en met als centraal conflict: %s".formatted(doelgroep, genre, setting, personages, conflict);
}
}

View File

@@ -0,0 +1,182 @@
package nl.agilecc.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.chat.request.ResponseFormat;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;
import nl.agilecc.model.AiVraag;
import nl.agilecc.model.Persona;
import nl.agilecc.model.Plot;
import nl.agilecc.model.Section;
import nl.agilecc.model.Story;
import nl.agilecc.model.UserInput;
import java.util.List;
public class OpenAiService {
private final String apiKey = System.getenv("OPENAI_API_KEY");
private final OpenAiChatModel openAiChatModel;
// private interface Assistant {
// String chat(String message);
// }
// private final Assistant assistant;
public OpenAiService() {
ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);
openAiChatModel = OpenAiChatModel.builder()
.baseUrl("http://langchain4j.dev/demo/openai/v1")
.apiKey(apiKey)
.modelName("gpt-4o-mini")
.build();
// assistant = AiServices.builder(Assistant.class)
// .chatModel(openAiChatModel)
// .chatMemory(chatMemory)
// .build();
}
public void hello() {
String answer = openAiChatModel.chat("Say 'Hello World!'");
// String answer = "dummy";
System.out.println(answer);
}
public void createStory() {
// TODO refine gather input
/*
- doelgroep: kleuters, kinderen, pubers, jong-volwassenen, volwassenen
- Genre, e.g. Actie, Avontuur, Grappig, Drama, Fantasy, Historische fictie, Mysterie, Romantisch, Science Fiction
- Setting / Waar vindt het verhaal plaats: (bijvb. een mistige heide, een bos vol mystieke ruines, een voetbalstadium, een planeet met futuristische steden, etc.)
- Wie komen er in voor? Bijvb. een avontuurlijke ridder, een jonge uitvinder, een knappe prins, een zelfstandige princes, een boze koning, etc.)
- Het centrale conflict? (een verloren schatkist, een op drift geraakt ruimteschip, een geliefde ontvoerd, enz.)
*/
String doelgroep = question("Wat is de doelgroep (e.g. kleuters, kinderen, pubers, jong-volwassenen, artsen, etc.)?", "kinderen");
String genre = question("Welk genre moet het zijn (e.g. Actie, Avontuur, Grappig, Drama, Fantasy, Historische fictie, Myserie, Romantisch, of Science Fiction)?", "Science Fiction");
String setting = question("Waar vindt het verhaal plaats (e.g. een mistige heide, een mos vol mystieke ruïnes, een voetbalsatium, een futuristische planeet)?", "Een buitenaardse savanne");
String wie = question("Wie komen er in voor (e.g. een avontuurlijke ridder, een jonge uitvinder, een knappe prinse)?", "Een boze koning, en een verstrooide verzetsheld");
String centraalConflict = question("Wat is het centrale conflict (e.g. een verloren schatkist, een op drift geraakt ruimteschipt, een ontvoerde geliefde)?", "Een verloren kist met buitenaardse spelcomputers");
UserInput userInput = new UserInput(doelgroep, genre, setting, wie, centraalConflict);
Plot plot = bepaalPlot(userInput);
IO.println("het plot %s".formatted(plot));
// List<Persona> personas = bepaalPersonages(userInput, plot);
// Plot herzienPlot = verbeterPlot(plot, personas);
// List<Section> blauwdruk = creeerBlauwdruk(herzienPlot, personas, userInput);
// List<Section> sections = schrijfSecties(blauwdruk);
// Story verhaal = schrijfVerhaal(sections);
// Story verhaalVersie2 = bepaalTitels(verhaal);
// Story verhaalVersie3 = maakPageTurner(verhaalVersie2);
// Story verhaalVersie4 = maakConsistent(verhaalVersie3, personas);
// Story verhaalVersie5 = killDarlings(verhaalVersie4);
//
// drukAf(verhaalVersie5);
// TODO schrijf (in een paar stappen) een plot. Laat terug komen waar het verhaal plaats vindt, wie een rol spelen in het verhaal, wat ze met elkaar te maken hebben, wie wat gaat doen en waarom, welke fases ze daarbij doorlopen in het verhaal, hoe ze zichzelf ontwikkelen gedurende deze fases, hoe het centrale probleem wordt opgelost
// TODO create personas voor de personen uit het plot. Geef een omschrijving van hun uiterlijk, een MBTI profiel, waar ze zijn opgegroeid, welke gebeurtenissen uit het verleden hen heeft gevormd, waar ze aan het begin van het verhaal leven en wat hen dagelijks bezig houdt.
// TODO Herschrijf het plot op basis van de personas
// TODO Schrijf op basis van het plot 8 +- 2 secties voor het verhaal. Schrijf voor elke sectie in 3 regels wat er gebeurd. Schrijf wie er wel en niet in voor komen. Welke ontwikkeling ze door maken. Wat in max. 10 woorden het doel is van de sectie
// TODO schrijf tekst voor elke sectie
// TODO herschrijf elke sectie zodat ze goed overgaan in de volgende en op de vorige sectie. Zorg aan het eind van elke sectie voor een cliffhanger
// TODO voeg alle secties samen tot één verhaal en schrap onnodige tussenwoorden en zinnen die geschrapt kunnen worden zonder afbreuk te doen aan het verhaal
// TODO Bepaal titel(s)
// TODO controleer structuur: corrigeer de tekst als het ergens teveel van het verhaal afwijkt, onnodig detail, onnodig herhalen van genoemde feiten,
// TODO contorleer consistentie: controleer of acties en dialogen overeen komen met hun persona's,
// TODO verwijder onnodige scenes
// IO.println("""
// Om een verhaal te maken stellen we je een aantal vragen.
// Het default antwoord staat er in haakjes achter
// Als je geen antwoord geeft, gebruikt hij het default antwoord.
// Als je niets wilt opvoeren, type dan 'GEEN'""");
//
// String leeftijd = question("Hoe oud ben je?", "10");
// String genre = question("Wat voor een type verhaal moet het worden?", "sprookje");
// String voorwerpen = question("Welke voorwerpen moeten er in voorkomen?", null);
// String personen = question("Welke personen moeten er in voorkomen?", null);
// String overig = question("Welke overige zaken moeten er in voorkomen?", null);
// String spanning = question("Op een schaal van 1 tot 10, hoe spannend moet het zijn?", "4");
//
// IO.println("Het verhaal wordt gegenereerd");
//
// String vraag1 = """
// Je rol is een schrijver.
// Schrijf een verhaal met minimaal 700 en maximaal 1000 worden.
// Het verhaal is voor iemand van %s jaar oud.
// Het moet een %s zijn.
// De personen die er in voor moeten komen zijn: %s
// De volgende voorwerpen moeten er in voorkomen: %s
// Verder moeten de volgende elementen terug komen: %s
// Op een schaal van 1 tot 10, is het spanningsniveau: %s"""
// .formatted(leeftijd, genre, personen, voorwerpen, overig, spanning);
// String resultaat = assistant.chat(vraag1);
//
// IO.println("Het verhaal wordt nog even geedit");
//
// String vraag2 = """
// Je rol is een editor.
// Je bekijkt het verhaal wat je als schrijver hebt gemaakt en herschrijft het.
// Hierbij let je op dat het taalgebruik klopt bij de doelgroep, dat korte en lange zinnen elkaar goed afwisselen,
// en dat er geen wollig taalgebruik in zit,
// en dat er geen onnodig moeilijke woorden in zit,
// en dat er een beetje tempo in het verhaal zit""";
//
// String resultaat2 = assistant.chat(vraag2);
//
// IO.println(resultaat2);
// IO.println("""
// We gaan een %s-verhaal schrijven voor iemand van %s jaar oud
// Het gaat over %s en er komen %s en %s in voor
// Het spanningsniveau is %s""".formatted(genre, leeftijd, personen, voorwerpen, overig, spanning));
}
private Plot bepaalPlot(UserInput userInput) {
ResponseFormat responseFormat = ResponseFormat.builder()
.type(ResponseFormat.JSON.type())
.jsonSchema(Plot.getJsonSchema())
.build();
AiVraag aiVraag = new AiVraag(
"Schrijver",
"Een startpunt voor een nieuw te schrijven verhaal",
Plot.omschrijvingPlot(),
userInput.toString()
);
ChatRequest chatRequest = ChatRequest.builder()
.responseFormat(responseFormat)
.messages(UserMessage.from(aiVraag.toString()))
.build();
ChatResponse chatResponse = openAiChatModel.chat(chatRequest);
try {
return new ObjectMapper().readValue(chatResponse.aiMessage().text(), Plot.class);
} catch (JsonProcessingException e) {
IO.println("Ik kon %s niet omzetten naar een Plot".formatted(chatResponse.aiMessage().text()));
return null;
}
}
private String question(String question, String defaultAwnser) {
String fallback = defaultAwnser == null ? "GEEN" : defaultAwnser;
String result = IO.readln(question + " (" + fallback + ")");
return isNotEmpty(result) ? result : defaultAwnser;
}
private boolean isNotEmpty(String input) {
return input != null && !input.trim().isEmpty();
}
}